From f5b91f0b844ba6a2c94fd74ea03895086de67aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 26 Mar 2012 02:45:01 -0400 Subject: [PATCH 01/47] libfreerdp-core: start integrating terminal server gateway code --- include/freerdp/crypto/crypto.h | 3 + include/freerdp/settings.h | 4 +- include/freerdp/types.h | 10 + libfreerdp-core/CMakeLists.txt | 4 + libfreerdp-core/rpch.c | 1397 +++++++++++++++++++++++++++++++ libfreerdp-core/rpch.h | 617 ++++++++++++++ libfreerdp-core/tsg.c | 273 ++++++ libfreerdp-core/tsg.h | 57 ++ libfreerdp-crypto/crypto.c | 36 + 9 files changed, 2400 insertions(+), 1 deletion(-) create mode 100644 libfreerdp-core/rpch.c create mode 100644 libfreerdp-core/rpch.h create mode 100644 libfreerdp-core/tsg.c create mode 100644 libfreerdp-core/tsg.h diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index dafbeaa1f..de135abda 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -142,4 +142,7 @@ FREERDP_API void crypto_rsa_private_decrypt(const uint8* input, int length, uint FREERDP_API void crypto_reverse(uint8* data, int length); FREERDP_API void crypto_nonce(uint8* nonce, int size); +FREERDP_API void crypto_base64_encode(uint8* data, int length, uint8** enc_data, int* res_length); +FREERDP_API void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length); + #endif /* FREERDP_CRYPTO_H */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 6b70a3dde..3982aae32 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -278,7 +278,9 @@ struct rdp_settings rdpBlob* password_cookie; /* 61 */ char* kerberos_kdc; /* 62 */ char* kerberos_realm; /* 63 */ - uint32 paddingC[80 - 64]; /* 64 */ + char* tsg_hostname; /* 64 */ + char* tsg_password; /* 65 */ + uint32 paddingC[80 - 66]; /* 66 */ /* User Interface Parameters */ boolean sw_gdi; /* 80 */ diff --git a/include/freerdp/types.h b/include/freerdp/types.h index 0934fa7f0..bce09650f 100644 --- a/include/freerdp/types.h +++ b/include/freerdp/types.h @@ -119,6 +119,16 @@ typedef int boolean; #include +typedef struct +{ + uint32 time_low; + uint16 time_mid; + uint16 time_hi_and_version; + uint8 clock_seq_hi_and_reserved; + uint8 clock_seq_low; + uint8 node[6]; +} uuid; + struct _RDP_PLUGIN_DATA { uint16 size; diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index b29b2b366..4ab065b7c 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -35,6 +35,8 @@ set(LIBFREERDP_CORE_SRCS nego.h info.c info.h + rpch.c + rpch.h input.c input.h license.c @@ -62,6 +64,8 @@ set(LIBFREERDP_CORE_SRCS rdp.h tcp.c tcp.h + tsg.c + tsg.h tpdu.c tpdu.h tpkt.c diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c new file mode 100644 index 000000000..be36dfa2f --- /dev/null +++ b/libfreerdp-core/rpch.c @@ -0,0 +1,1397 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include + +#include + +#include "rpch.h" + +#define HTTP_STREAM_SIZE 0xFFFF + +rdpRpch* rpch_new(rdpSettings* settings) +{ + rdpRpch* rpch; + rpch = (rdpRpch*) xzalloc(sizeof(rdpRpch)); + + rpch->http_in = (rdpRpchHTTP*) xzalloc(sizeof(rdpRpchHTTP)); + rpch->http_out = (rdpRpchHTTP*) xzalloc(sizeof(rdpRpchHTTP)); + + //rpch->http_in->ntht = ntlmssp_client_new(); + //rpch->http_out->ntht = ntlmssp_client_new(); + rpch->http_in->state = RPCH_HTTP_DISCONNECTED; + rpch->http_out->state = RPCH_HTTP_DISCONNECTED; + + rpch->read_buffer = NULL; + rpch->write_buffer = NULL; + rpch->read_buffer_len = 0; + rpch->write_buffer_len = 0; + + rpch->BytesReceived = 0; + rpch->AwailableWindow = 0; + rpch->BytesSent = 0; + rpch->RecAwailableWindow = 0; + + rpch->settings = settings; + + //rpch->ntlmssp = ntlmssp_client_new(); + + rpch->call_id = 0; + return rpch; +} + +boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out) +{ + rpch->tcp_in = tcp_in; + rpch->tcp_out = tcp_out; + rpch->tls_in = tls_in; + rpch->tls_out = tls_out; + + return true; +} + +boolean rpch_out_connect_http(rdpRpch* rpch) +{ + rdpTls* tls_out = rpch->tls_out; + rdpSettings* settings = rpch->settings; + rdpRpchHTTP* http_out = rpch->http_out; + //NTLMSSP* http_out_ntlmssp = http_out->ntht; + + STREAM* ntlmssp_stream; + STREAM* http_stream; + + ntlmssp_stream = stream_new(0xFFFF); + http_stream = stream_new(0xFFFF); + + uint8* decoded_ntht_data = NULL; + int decoded_ntht_length; + uint8* encoded_ntht_data = NULL; + int encoded_ntht_length; + + //ntlmssp_set_username(http_out_ntlmssp, settings->username); + //ntlmssp_set_password(http_out_ntlmssp, settings->password); + //ntlmssp_set_domain(http_out_ntlmssp, settings->domain); + //ntlmssp_set_workstation(http_out_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ + + //ntlmssp_send(http_out_ntlmssp, ntlmssp_stream); + + decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_data = xmalloc(decoded_ntht_length); + + ntlmssp_stream->p = ntlmssp_stream->data; + stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); + + stream_write(http_stream, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); + stream_write(http_stream, "Accept: application/rpc\n", 24); + stream_write(http_stream, "Cache-Control: no-cache\n", 24); + stream_write(http_stream, "Connection: Keep-Alive\n", 23); + stream_write(http_stream, "Content-Length: 0\n", 18); + stream_write(http_stream, "User-Agent: MSRPC\n", 18); + stream_write(http_stream, "Host: ", 6); + stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); + stream_write(http_stream, "\n", 1); + stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); + stream_write(http_stream, "Authorization: NTLM ", 20); + stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); + stream_write(http_stream, "\n\n", 2); + + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + tls_write(tls_out, http_stream->data, http_stream->p - http_stream->data); + stream_clear(http_stream); + http_stream->p = http_stream->data; + + xfree(decoded_ntht_data); + + encoded_ntht_length = -1; + xfree(encoded_ntht_data); + encoded_ntht_data = NULL; + uint8 buffer_byte; + http_out->contentLength = 0; + + /* Example for how not to do clear code, sorry for that */ + while (true) /* TODO make proper reading */ + { + tls_read(tls_out, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + + if (encoded_ntht_length == -1) + { + uint8* start_of_ntht_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); + + if (start_of_ntht_data != NULL) + { + start_of_ntht_data += 5; + + for (encoded_ntht_length = 0; ; encoded_ntht_length++) + { + tls_read(tls_out, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + + if (start_of_ntht_data[encoded_ntht_length] == '\n') + { + encoded_ntht_length--; /* \r */ + break; + } + } + + encoded_ntht_data = xmalloc(encoded_ntht_length); + memcpy(encoded_ntht_data, start_of_ntht_data, encoded_ntht_length); + } + } + + if (http_out->contentLength == 0) + { + if (strstr((char*) http_stream->data, "Content-Length: ") != NULL) + { + int i = 0; + + while (*(http_stream->p-1) != '\n') + { + tls_read(tls_out, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + i++; + } + + http_out->contentLength = strtol((char*)(http_stream->p-i),NULL,10); + } + } + + if (*(http_stream->p-1) == '\n' && *(http_stream->p-3) == '\n') + { + int i; + + for(i = 0; i < http_out->contentLength; i++) + { + tls_read(tls_out, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + } + + break; + } + } + /* Example end */ + + DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); + stream_clear(http_stream); + http_stream->p = http_stream->data; + + if (encoded_ntht_length == 0) /* No NTLM data was found */ + return false; + + crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); + + stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + ntlmssp_stream->p = ntlmssp_stream->data; + + xfree(decoded_ntht_data); + xfree(encoded_ntht_data); + + //ntlmssp_recv(http_out_ntlmssp, ntlmssp_stream); + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + //ntlmssp_send(http_out_ntlmssp, ntlmssp_stream); + + decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_data = xmalloc(decoded_ntht_length); + ntlmssp_stream->p = ntlmssp_stream->data; + stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); + + stream_write(http_stream, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); + stream_write(http_stream, "Accept: application/rpc\n", 24); + stream_write(http_stream, "Cache-Control: no-cache\n", 24); + stream_write(http_stream, "Connection: Keep-Alive\n", 23); + stream_write(http_stream, "Content-Length: 76\n", 19); + stream_write(http_stream, "User-Agent: MSRPC\n", 18); + stream_write(http_stream, "Host: ", 6); + stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); + stream_write(http_stream, "\n", 1); + stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); + stream_write(http_stream, "Authorization: NTLM ", 20); + stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); + stream_write(http_stream, "\n\n", 2); + + http_out->contentLength = 76; + http_out->remContentLength = 76; + + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + + tls_write(tls_out, http_stream->data, http_stream->p - http_stream->data); + + stream_clear(http_stream); + http_stream->p = http_stream->data; + + xfree(decoded_ntht_data); + xfree(encoded_ntht_data); + /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ + + http_out->state = RPCH_HTTP_SENDING; + + return true; +} + +boolean rpch_in_connect_http(rdpRpch* rpch) +{ + rdpTls* tls_in = rpch->tls_in; + rdpSettings* settings = rpch->settings; + rdpRpchHTTP* http_in = rpch->http_in; + //NTLMSSP* http_in_ntlmssp = http_in->ntht; + + STREAM* ntlmssp_stream; + STREAM* http_stream; + + ntlmssp_stream = stream_new(0xFFFF); + http_stream = stream_new(0xFFFF); + + uint8* decoded_ntht_data = NULL; + int decoded_ntht_length; + uint8* encoded_ntht_data = NULL; + int encoded_ntht_length; + + //ntlmssp_set_username(http_in_ntlmssp, settings->username); + //ntlmssp_set_password(http_in_ntlmssp, settings->password); + //ntlmssp_set_domain(http_in_ntlmssp, settings->domain); + //ntlmssp_set_workstation(http_in_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ + + //ntlmssp_send(http_in_ntlmssp,ntlmssp_stream); + + decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_data = xmalloc(decoded_ntht_length); + + ntlmssp_stream->p = ntlmssp_stream->data; + stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); + + stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); + stream_write(http_stream, "Accept: application/rpc\n", 24); + stream_write(http_stream, "Cache-Control: no-cache\n", 24); + stream_write(http_stream, "Connection: Keep-Alive\n", 23); + stream_write(http_stream, "Content-Length: 0\n", 18); + stream_write(http_stream, "User-Agent: MSRPC\n", 18); + stream_write(http_stream, "Host: ", 6); + stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); + stream_write(http_stream, "\n", 1); + stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); + stream_write(http_stream, "Authorization: NTLM ", 20); + stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); + stream_write(http_stream, "\n\n", 2); + + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data); + stream_clear(http_stream); + http_stream->p = http_stream->data; + + xfree(decoded_ntht_data); + + encoded_ntht_length = -1; + xfree(encoded_ntht_data); + encoded_ntht_data = NULL; + uint8 buffer_byte; + http_in->contentLength = 0; + + /* Example for how not to do clear code, sorry for that */ + while (true) /* TODO make proper reading */ + { + tls_read(tls_in, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + + if (encoded_ntht_length == -1) + { + uint8* start_of_ntht_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); + + if (start_of_ntht_data != NULL) + { + start_of_ntht_data += 5; + + for (encoded_ntht_length=0;;encoded_ntht_length++) + { + tls_read(tls_in, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + + if (start_of_ntht_data[encoded_ntht_length]=='\n') + { + encoded_ntht_length--; /* \r */ + break; + } + } + + encoded_ntht_data = xmalloc(encoded_ntht_length); + memcpy(encoded_ntht_data, start_of_ntht_data, encoded_ntht_length); + } + } + + if (http_in->contentLength == 0) + { + if (strstr((char*) http_stream->data, "Content-Length: ") != NULL) + { + int i = 0; + + while (*(http_stream->p-1) != '\n') + { + tls_read(tls_in, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + i++; + } + + http_in->contentLength = strtol((char*)(http_stream->p-i), NULL, 10); + } + } + + if (*(http_stream->p - 1) == '\n' && *(http_stream->p - 3) == '\n') + { + int i; + + for(i = 0; i < http_in->contentLength; i++) + { + tls_read(tls_in, &buffer_byte, 1); + stream_write(http_stream, &buffer_byte, 1); + } + + break; + } + } + /* Example end */ + + DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); + stream_clear(http_stream); + http_stream->p = http_stream->data; + + if (encoded_ntht_length == 0) /* No NTLM data was found */ + return false; + + crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); + + stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + ntlmssp_stream->p = ntlmssp_stream->data; + + xfree(decoded_ntht_data); + xfree(encoded_ntht_data); + + //ntlmssp_recv(http_in_ntlmssp, ntlmssp_stream); + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + //ntlmssp_send(http_in_ntlmssp, ntlmssp_stream); + + decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_data = xmalloc(decoded_ntht_length); + ntlmssp_stream->p = ntlmssp_stream->data; + stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + + stream_clear(ntlmssp_stream); + ntlmssp_stream->p = ntlmssp_stream->data; + + crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); + + stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); + stream_write(http_stream, "Accept: application/rpc\n", 24); + stream_write(http_stream, "Cache-Control: no-cache\n", 24); + stream_write(http_stream, "Connection: Keep-Alive\n", 23); + stream_write(http_stream, "Content-Length: 1073741824\n", 27); + stream_write(http_stream, "User-Agent: MSRPC\n", 18); + stream_write(http_stream, "Host: ", 6); + stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); + stream_write(http_stream, "\n", 1); + stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); + stream_write(http_stream, "Authorization: NTLM ", 20); + stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); + stream_write(http_stream, "\n\n", 2); + + http_in->contentLength = 1073741824; + http_in->remContentLength = 1073741824; + + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + + tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data); + + stream_clear(http_stream); + http_stream->p = http_stream->data; + + xfree(decoded_ntht_data); + xfree(encoded_ntht_data); + /* At this point IN connection is ready to send CONN/B1 and start with sending data */ + + http_in->state = RPCH_HTTP_SENDING; + + return true; +} + +int rpch_out_write(rdpRpch* rpch, uint8* data, int length) +{ + int sent = 0; + int status = -1; + rdpRpchHTTP* http_out = rpch->http_out; + rdpTls* tls_out = rpch->tls_out; + + if (http_out->state == RPCH_HTTP_DISCONNECTED) + if (!rpch_out_connect_http(rpch)) + return false; + + if (http_out->remContentLength < length) + { + printf("RPCH Error: HTTP frame is over.\n"); + return -1; /* TODO ChannelRecycling */ + } + +#ifdef WITH_DEBUG_RPCH + printf("rpch_out_write(): length: %d\n", length); + freerdp_hexdump(data, length); + printf("\n"); +#endif + + while (sent < length) + { + status = tls_write(tls_out, data + sent, length - sent); + + if (status <= 0) + return status; /* TODO no idea how to handle errors */ + + sent += status; + } + + http_out->remContentLength -= sent; + + return sent; +} + +int rpch_in_write(rdpRpch* rpch, uint8* data, int length) +{ + int sent = 0; + int status = -1; + rdpRpchHTTP* http_in = rpch->http_in; + rdpTls* tls_in = rpch->tls_in; + + if (http_in->state == RPCH_HTTP_DISCONNECTED) + if (!rpch_in_connect_http(rpch)) + return -1; + + if (http_in->remContentLength < length) + { + printf("RPCH Error: HTTP frame is over.\n"); + return -1;/* TODO ChannelRecycling */ + } + +#ifdef WITH_DEBUG_RPCH + printf("\nrpch_in_send(): length: %d, remaining content length: %d\n", length, http_in->remContentLength); + freerdp_hexdump(data, length); + printf("\n"); +#endif + + while (sent < length) + { + status = tls_write(tls_in, data+sent, length-sent); + + if (status <= 0) + return status; /* TODO no idea how to handle errors */ + + sent += status; + } + + rpch->BytesSent += sent; + http_in->remContentLength -= sent; + + return sent; +} + +uint8* rpch_create_cookie() +{ + uint8 *ret = xmalloc(16); + RAND_pseudo_bytes(ret, 16); + return ret; +} + +boolean rpch_out_send_CONN_A1(rdpRpch* rpch) +{ + STREAM* pdu = stream_new(76); + + 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 = 76; + uint16 auth_length = 0; + uint32 call_id = 0x00000000; + uint16 flags = 0x0000; + uint16 num_commands = 0x0004; + + /* Version */ + uint32 vCommandType = 0x00000006; + uint32 Version = 0x00000001; + + /* VirtualConnectionCookie */ + uint32 vccCommandType = 0x00000003; + rpch->virtualConnectionCookie = rpch_create_cookie(); /* 16 bytes */ + + /* OUTChannelCookie */ + uint32 occCommandType = 0x00000003; + rpch->OUTChannelCookie = rpch_create_cookie(); /* 16 bytes */ + + /* ReceiveWindowSize */ + uint32 rwsCommandType = 0x00000000; + uint32 reseiveWindowSize = 0x00010000; + rpch->AwailableWindow = reseiveWindowSize; + + stream_write_uint8(pdu, rpc_vers); + stream_write_uint8(pdu, rpc_vers_minor); + stream_write_uint8(pdu, ptype); + stream_write_uint8(pdu, pfc_flags); + stream_write_uint32(pdu, packet_drep); + stream_write_uint16(pdu, frag_length); + stream_write_uint16(pdu, auth_length); + stream_write_uint32(pdu, call_id); + stream_write_uint16(pdu, flags); + stream_write_uint16(pdu, num_commands); + stream_write_uint32(pdu, vCommandType); + stream_write_uint32(pdu, Version); + stream_write_uint32(pdu, vccCommandType); + stream_write(pdu, rpch->virtualConnectionCookie, 16); + stream_write_uint32(pdu, occCommandType); + stream_write(pdu, rpch->OUTChannelCookie, 16); + stream_write_uint32(pdu, rwsCommandType); + stream_write_uint32(pdu, reseiveWindowSize); + + rpch_out_write(rpch, pdu->data, pdu->p - pdu->data); + + stream_free(pdu); + + return true; +} + +boolean rpch_in_send_CONN_B1(rdpRpch* rpch) +{ + STREAM* pdu = stream_new(104); + + 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 = 104; + uint16 auth_length = 0; + uint32 call_id = 0x00000000; + uint16 flags = 0x0000; + uint16 num_commands = 0x0006; + + /* Version */ + uint32 vCommandType = 0x00000006; + uint32 Version = 0x00000001; + + /* VirtualConnectionCookie */ + uint32 vccCommandType = 0x00000003; + + /* INChannelCookie */ + uint32 iccCommandType = 0x00000003; + rpch->INChannelCookie = rpch_create_cookie(); /* 16bytes */ + + /* ChannelLifetime */ + uint32 clCommandType = 0x00000004; + uint32 ChannelLifetime = 0x40000000; + + /* ClientKeepalive */ + uint32 ckCommandType = 0x00000005; + uint32 ClientKeepalive = 0x000493e0; + + /* AssociationGroupId */ + uint32 agidCommandType = 0x0000000c; + uint8* AssociationGroupId = rpch_create_cookie(); /* 16 bytes */ + + stream_write_uint8(pdu, rpc_vers); + stream_write_uint8(pdu, rpc_vers_minor); + stream_write_uint8(pdu, ptype); + stream_write_uint8(pdu, pfc_flags); + stream_write_uint32(pdu, packet_drep); + stream_write_uint16(pdu, frag_length); + stream_write_uint16(pdu, auth_length); + stream_write_uint32(pdu, call_id); + stream_write_uint16(pdu, flags); + stream_write_uint16(pdu, num_commands); + stream_write_uint32(pdu, vCommandType); + stream_write_uint32(pdu, Version); + stream_write_uint32(pdu, vccCommandType); + stream_write(pdu, rpch->virtualConnectionCookie, 16); + stream_write_uint32(pdu, iccCommandType); + stream_write(pdu, rpch->INChannelCookie, 16); + stream_write_uint32(pdu, clCommandType); + stream_write_uint32(pdu, ChannelLifetime); + stream_write_uint32(pdu, ckCommandType); + stream_write_uint32(pdu, ClientKeepalive); + stream_write_uint32(pdu, agidCommandType); + stream_write(pdu, AssociationGroupId, 16); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + stream_free(pdu); + + return true; +} + +boolean rpch_in_send_keep_alive(rdpRpch* rpch) +{ + STREAM* pdu = 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; + + /* ClientKeepalive */ + uint32 ckCommandType = 0x00000005; + uint32 ClientKeepalive = 0x00007530; + + stream_write_uint8(pdu, rpc_vers); + stream_write_uint8(pdu, rpc_vers_minor); + stream_write_uint8(pdu, ptype); + stream_write_uint8(pdu, pfc_flags); + stream_write_uint32(pdu, packet_drep); + stream_write_uint16(pdu, frag_length); + stream_write_uint16(pdu, auth_length); + stream_write_uint32(pdu, call_id); + stream_write_uint16(pdu, flags); + stream_write_uint16(pdu, num_commands); + stream_write_uint32(pdu, ckCommandType); + stream_write_uint32(pdu, ClientKeepalive); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + stream_free(pdu); + + return true; +} + +boolean rpch_in_send_bind(rdpRpch* rpch) +{ + STREAM* ntlm_stream = stream_new(0xFFFF); + //rpch->ntlmssp = ntlmssp_client_new(); + //rpch->ntlmssp->ntlm_v2 = true; + //rpch->ntlmssp->do_not_seal = true; + //ntlmssp_set_username(rpch->ntlmssp, "PanoGatewayUser49"); + //ntlmssp_set_password(rpch->ntlmssp, rpch->settings->tsg_password); + //ntlmssp_set_domain(rpch->ntlmssp, "PANOGATEWAY"); + //ntlmssp_set_workstation(rpch->ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ + + //ntlmssp_send(rpch->ntlmssp,ntlm_stream); + + rpcconn_bind_hdr_t* bind_pdu = xmalloc(sizeof(rpcconn_bind_hdr_t)); + bind_pdu->rpc_vers = 5; + bind_pdu->rpc_vers_minor = 0; + bind_pdu->PTYPE = PTYPE_BIND; + bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX; + bind_pdu->packed_drep[0] = 0x10;bind_pdu->packed_drep[1] = 0x00;bind_pdu->packed_drep[2] = 0x00;bind_pdu->packed_drep[3] = 0x00; + bind_pdu->frag_length = 124 + (ntlm_stream->p - ntlm_stream->data); + bind_pdu->auth_length = ntlm_stream->p - ntlm_stream->data; + bind_pdu->call_id = 2; + bind_pdu->max_xmit_frag = 0x0FF8; + bind_pdu->max_recv_frag = 0x0FF8; + bind_pdu->assoc_group_id = 0; + bind_pdu->p_context_elem.n_context_elem = 2; + bind_pdu->p_context_elem.reserved = 0; + bind_pdu->p_context_elem.reserved2 = 0; + bind_pdu->p_context_elem.p_cont_elem = xmalloc(sizeof(p_cont_elem_t) * bind_pdu->p_context_elem.n_context_elem); + bind_pdu->p_context_elem.p_cont_elem[0].p_cont_id = 0; + bind_pdu->p_context_elem.p_cont_elem[0].n_transfer_syn = 1; + bind_pdu->p_context_elem.p_cont_elem[0].reserved = 0; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_low = 0x44e265dd; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_mid = 0x7daf; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_low = 0x60; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[0] = 0x3c; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[1] = 0xdb; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[2] = 0x6e; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[3] = 0x7a; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[4] = 0x27; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[5] = 0x29; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_version = 0x00030001; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes = xmalloc(sizeof(p_syntax_id_t)); + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_low = 0x8a885d04; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_mid = 0x1ceb; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x11c9; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x9f; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_low = 0xe8; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[0] = 0x08; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[1] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[2] = 0x2b; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[3] = 0x10; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[4] = 0x48; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[5] = 0x60; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_version = 0x00000002; + bind_pdu->p_context_elem.p_cont_elem[1].p_cont_id = 1; + bind_pdu->p_context_elem.p_cont_elem[1].n_transfer_syn = 1; + bind_pdu->p_context_elem.p_cont_elem[1].reserved = 0; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_low = 0x44e265dd; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_mid = 0x7daf; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_low = 0x60; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[0] = 0x3c; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[1] = 0xdb; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[2] = 0x6e; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[3] = 0x7a; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[4] = 0x27; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[5] = 0x29; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_version = 0x00030001; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes = xmalloc(sizeof(p_syntax_id_t)); + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_low = 0x6cb71c2c; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_mid = 0x9812; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x4540; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x03; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_low = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[0] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[1] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[2] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[3] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[4] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[5] = 0x00; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_version = 0x00000001; + bind_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p*/ + bind_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */ + bind_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ + bind_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */ + bind_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ + bind_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ + bind_pdu->auth_verifier.auth_value = xmalloc(bind_pdu->auth_length); /* credentials; size_is(auth_length) p*/; + memcpy(bind_pdu->auth_verifier.auth_value, ntlm_stream->data, bind_pdu->auth_length); + + stream_free(ntlm_stream); + + STREAM* pdu = stream_new(bind_pdu->frag_length); + + stream_write(pdu, bind_pdu, 24); + stream_write(pdu, &bind_pdu->p_context_elem, 4); + stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem, 24); + stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes, 20); + stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem + 1, 24); + stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes, 20); + + if (bind_pdu->auth_verifier.auth_pad_length > 0) + stream_write(pdu, bind_pdu->auth_verifier.auth_pad, bind_pdu->auth_verifier.auth_pad_length); + + stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ + stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + /* TODO there is some allocated memory */ + xfree(bind_pdu); + + return true; +} + +boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) +{ + STREAM* ntlm_stream = stream_new(0xFFFF); + + //ntlmssp_send(rpch->ntlmssp,ntlm_stream); + + rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu = xmalloc(sizeof(rpcconn_rpc_auth_3_hdr_t)); + rpc_auth_3_pdu->rpc_vers = 5; + rpc_auth_3_pdu->rpc_vers_minor = 0; + rpc_auth_3_pdu->PTYPE = PTYPE_RPC_AUTH_3; + rpc_auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX; + rpc_auth_3_pdu->packed_drep[0] = 0x10; + rpc_auth_3_pdu->packed_drep[1] = 0x00; + rpc_auth_3_pdu->packed_drep[2] = 0x00; + rpc_auth_3_pdu->packed_drep[3] = 0x00; + rpc_auth_3_pdu->frag_length = 28 + (ntlm_stream->p - ntlm_stream->data); + rpc_auth_3_pdu->auth_length = ntlm_stream->p - ntlm_stream->data; + rpc_auth_3_pdu->call_id = 2; + rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; + rpc_auth_3_pdu->max_recv_frag = 0x0FF8; + rpc_auth_3_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p */ + rpc_auth_3_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */ + rpc_auth_3_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ + rpc_auth_3_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */ + rpc_auth_3_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ + rpc_auth_3_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ + rpc_auth_3_pdu->auth_verifier.auth_value = xmalloc(rpc_auth_3_pdu->auth_length); /* credentials; size_is(auth_length) p */ + memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, ntlm_stream->data, rpc_auth_3_pdu->auth_length); + + stream_free(ntlm_stream); + + STREAM* pdu = stream_new(rpc_auth_3_pdu->frag_length); + + stream_write(pdu, rpc_auth_3_pdu, 20); + + if (rpc_auth_3_pdu->auth_verifier.auth_pad_length > 0) + stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_pad, rpc_auth_3_pdu->auth_verifier.auth_pad_length); + + stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8); + stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + xfree(rpc_auth_3_pdu); + + return true; +} + +boolean rpch_in_send_flow_control(rdpRpch* rpch) +{ + STREAM* pdu = stream_new(56); + + 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 = 56; + uint16 auth_length = 0; + uint32 call_id = 0x00000000; + uint16 flags = 0x0002; + uint16 num_commands = 0x0002; + + /* ClientKeepalive */ + uint32 ckCommandType = 0x0000000d; + uint32 ClientKeepalive = 0x00000003; + + /* */ + uint32 a = 0x00000001; + uint32 aa = rpch->BytesReceived; + uint32 aaa = 0x00010000; + rpch->AwailableWindow = aaa; + + uint8* b = rpch->OUTChannelCookie; + + stream_write_uint8(pdu, rpc_vers); + stream_write_uint8(pdu, rpc_vers_minor); + stream_write_uint8(pdu, ptype); + stream_write_uint8(pdu, pfc_flags); + stream_write_uint32(pdu, packet_drep); + stream_write_uint16(pdu, frag_length); + stream_write_uint16(pdu, auth_length); + stream_write_uint32(pdu, call_id); + stream_write_uint16(pdu, flags); + stream_write_uint16(pdu, num_commands); + stream_write_uint32(pdu, ckCommandType); + stream_write_uint32(pdu, ClientKeepalive); + stream_write_uint32(pdu, a); + stream_write_uint32(pdu, aa); + stream_write_uint32(pdu, aaa); + stream_write(pdu, b, 16); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + stream_free(pdu); + + return true; +} + +boolean rpch_in_send_ping(rdpRpch* rpch) +{ + STREAM* pdu = stream_new(20); + + 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 = 56; + uint16 auth_length = 0; + uint32 call_id = 0x00000000; + uint16 flags = 0x0001; + uint16 num_commands = 0x0000; + + stream_write_uint8(pdu, rpc_vers); + stream_write_uint8(pdu, rpc_vers_minor); + stream_write_uint8(pdu, ptype); + stream_write_uint8(pdu, pfc_flags); + stream_write_uint32(pdu, packet_drep); + stream_write_uint16(pdu, frag_length); + stream_write_uint16(pdu, auth_length); + stream_write_uint32(pdu, call_id); + stream_write_uint16(pdu, flags); + stream_write_uint16(pdu, num_commands); + + rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + stream_free(pdu); + + return true; +} + +int rpch_out_read_http_header(rdpRpch* rpch) +{ + int status; + rdpTls* tls_out = rpch->tls_out; + rdpRpchHTTP* http_out = rpch->http_out; + STREAM* http_stream; + + http_stream = stream_new(1024); /* hope the header will not be larger */ + http_out->contentLength = 0; + + while (true) /* TODO make proper reading */ + { + status = tls_read(tls_out, stream_get_tail(http_stream), 1); + + if (status < 0) + return status; + + stream_seek(http_stream, 1); + + if (http_out->contentLength == 0) + { + if (strstr((char*) stream_get_head(http_stream), "Content-Length:") != NULL) + { + int i = 0; + + while (*(stream_get_tail(http_stream)-1) != '\n') + { + status = tls_read(tls_out, stream_get_tail(http_stream), 1); + + if (status < 0) + return status; + + stream_seek(http_stream, 1); + i++; + + if (*(stream_get_tail(http_stream)-1) == ' ') + i--; + } + + http_out->contentLength = strtol((char*) (stream_get_tail(http_stream) - i), NULL, 10); + http_out->remContentLength = http_out->contentLength; + } + } + + if (*(stream_get_tail(http_stream) - 1) == '\n' && *(stream_get_tail(http_stream) - 3) == '\n') + { + break; + } + } + + DEBUG_RPCH("\nRecv HTTP header:\n%s", stream_get_head(http_stream)); + stream_free(http_stream); + + return status; +} + +int rpch_proceed_RTS(rdpRpch* rpch, 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) + { + rpch_in_send_keep_alive(rpch); + 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 rpch_out_read(rdpRpch* rpch, uint8* data, int length) +{ + int status; + uint8* pdu; + uint8 ptype; + uint16 frag_length; + rdpTls* tls_out = rpch->tls_out; + rdpRpchHTTP* http_out = rpch->http_out; + + if (rpch->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ + rpch_in_send_flow_control(rpch); /* Send FlowControlAck every time AW reaches the half */ + + if (http_out->remContentLength <= 0xFFFF) /* TODO make ChannelRecycling */ + if (rpch_out_read_http_header(rpch) < 0) + return -1; + + pdu = xmalloc(0xFFFF); + + status = tls_read(tls_out, pdu, 10); + + if (status <= 0) /* read first 10 bytes to get the frag_length value */ + { + xfree(pdu); + return status; + } + + ptype = *(pdu + 2); + frag_length = *((uint16*) (pdu + 8)); + + status = tls_read(tls_out, pdu + 10, frag_length - 10); + + if (status < 0) + { + xfree(pdu); + return status; + } + + if (ptype == 0x14) /* RTS PDU */ + { + rpch_proceed_RTS(rpch, pdu, frag_length); + xfree(pdu); + return 0; + } + else + { + rpch->BytesReceived += frag_length; /* RTS PDUs are not subjects for FlowControl */ + rpch->AwailableWindow -= frag_length; + } + + http_out->remContentLength -= frag_length; + + if (length < frag_length) + { + printf("rcph_out_read(): Error! Given buffer is to small. Recieved data fits not in.\n"); + xfree(pdu); + return -1; /* TODO add buffer for storing remaining data for the next read in case destination buffer is too small */ + } + + memcpy(data, pdu, frag_length); + +#ifdef WITH_DEBUG_RPCH + printf("\nrpch_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); + freerdp_hexdump(data, frag_length); + printf("\n"); +#endif + + xfree(pdu); + + return frag_length; +} + +int rpch_out_recv_bind_ack(rdpRpch* rpch) +{ + int pdu_length = 0x8FFF; /* 32KB buffer */ + uint8* pdu = xmalloc(pdu_length); + int status = rpch_out_read(rpch, pdu, pdu_length); + + if (status > 0) + { + uint16 frag_length = *((uint16*)(pdu + 8)); + uint16 auth_length = *((uint16*)(pdu + 10)); + + STREAM* ntlmssp_stream = stream_new(0xFFFF); + stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); + ntlmssp_stream->p = ntlmssp_stream->data; + + //ntlmssp_recv(rpch->ntlmssp, ntlmssp_stream); + + stream_free(ntlmssp_stream); + } + + xfree(pdu); + return status; +} + +int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) +{ + int i; + int status = -1; + + uint8 auth_pad_length = 16 - ((24 + length + 8 + 16) % 16); + + if (auth_pad_length == 16) + auth_pad_length = 0; + + rpcconn_request_hdr_t* request_pdu = xmalloc(sizeof(rpcconn_request_hdr_t)); + request_pdu->rpc_vers = 5; + request_pdu->rpc_vers_minor = 0; + request_pdu->PTYPE = PTYPE_REQUEST; + request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; + request_pdu->packed_drep[0] = 0x10; + request_pdu->packed_drep[1] = 0x00; + request_pdu->packed_drep[2] = 0x00; + request_pdu->packed_drep[3] = 0x00; + request_pdu->frag_length = 24 + length + auth_pad_length + 8 + 16; + request_pdu->auth_length = 16; + request_pdu->call_id = ++rpch->call_id; + + /* opnum=8 means [MS-TSGU] TsProxySetupRecievePipe, save call_id for checking pipe responses */ + + if (opnum == 8) + rpch->pipe_call_id=rpch->call_id; + + request_pdu->alloc_hint = length; + request_pdu->p_cont_id = 0x0000; + request_pdu->opnum = opnum; + request_pdu->stub_data = data; + request_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authentication service */ + request_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ + request_pdu->auth_verifier.auth_pad_length = auth_pad_length; /* :01 */ + request_pdu->auth_verifier.auth_pad = xmalloc(auth_pad_length); /* align(4); size_is(auth_pad_length) p */ + + for (i = 0; i < auth_pad_length; i++) + request_pdu->auth_verifier.auth_pad[i] = 0x00; + + request_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ + request_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ + request_pdu->auth_verifier.auth_value = xmalloc(request_pdu->auth_length); /* credentials; size_is(auth_length) p */ + + STREAM* pdu = stream_new(request_pdu->frag_length); + + stream_write(pdu, request_pdu, 24); + stream_write(pdu, request_pdu->stub_data, request_pdu->alloc_hint); + + if (request_pdu->auth_verifier.auth_pad_length > 0) + stream_write(pdu, request_pdu->auth_verifier.auth_pad, request_pdu->auth_verifier.auth_pad_length); + + stream_write(pdu, &request_pdu->auth_verifier.auth_type, 8); + + rdpBlob rdpMsg; + rdpMsg.data = pdu->data; + rdpMsg.length = pdu->p - pdu->data; + //ntlmssp_encrypt_message(rpch->ntlmssp, &rdpMsg, NULL, request_pdu->auth_verifier.auth_value); + + stream_write(pdu, request_pdu->auth_verifier.auth_value, request_pdu->auth_length); + + status = rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + + xfree(request_pdu->auth_verifier.auth_value); + xfree(request_pdu->auth_verifier.auth_pad); + xfree(request_pdu); + + if (status < 0) + { + printf("rpch_write(): Error! rcph_in_write returned negative value.\n"); + return status; + } + + return length; +} + +int rpch_read(rdpRpch* rpch, uint8* data, int length) +{ + int rpch_length = length + 0xFF; + int status; + int readed = 0; + int data_length; + uint8* rpch_data = xmalloc(rpch_length); + uint16 frag_length; + uint16 auth_length; + uint8 auth_pad_length; + uint32 call_id = -1; + + if (rpch->read_buffer_len > 0) + { + if (rpch->read_buffer_len > length) + { + /*TODO fix read_buffer is too long problem */ + printf("ERROR! RPCH Stores data in read_buffer fits not in data on rpch_read.\n"); + return -1; + } + + memcpy(data, rpch->read_buffer, rpch->read_buffer_len); + readed += rpch->read_buffer_len; + xfree(rpch->read_buffer); + rpch->read_buffer_len = 0; + } + + while (true) + { + status = rpch_out_read(rpch, rpch_data, rpch_length); + + if (status == 0) + { + xfree(rpch_data); + return readed; + } + else if (status < 0) + { + printf("\nError! rpch_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", + rpch->BytesSent, rpch->BytesReceived); + + xfree(rpch_data); + return status; + } + + frag_length = *(uint16*)(rpch_data + 8); + auth_length = *(uint16*)(rpch_data + 10); + call_id = *(uint32*)(rpch_data + 12); + status = *(uint32*)(rpch_data + 16); /* alloc_hint */ + auth_pad_length = *(rpch_data + frag_length - auth_length - 6); /* -6 = -8 + 2 (sec_trailer + 2) */ + + /* data_length must be calculated because alloc_hint carries size of more than one pdu */ + data_length = frag_length - auth_length - 24 - 8 - auth_pad_length; /* 24 is header; 8 is sec_trailer */ + + if (status == 4) + continue; + + if (readed + data_length > length) /* if read data is greater then given buffer */ + { + rpch->read_buffer_len = readed + data_length - length; + rpch->read_buffer = xmalloc(rpch->read_buffer_len); + + data_length -= rpch->read_buffer_len; + + memcpy(rpch->read_buffer, rpch_data + 24 + data_length, rpch->read_buffer_len); + } + + memcpy(data + readed, rpch_data + 24, data_length); + + readed += data_length; + + if (status > data_length && readed < length) + continue; + + break; + } + + xfree(rpch_data); + return readed; +} + +boolean rpch_connect(rdpRpch* rpch) +{ + int status; + uint8* pdu; + int pdu_length; + + if (!rpch_out_send_CONN_A1(rpch)) + { + printf("rpch_out_send_CONN_A1 fault!\n"); + return false; + } + + pdu_length = 0xFFFF; + pdu = xmalloc(pdu_length); + + status = rpch_out_read(rpch, pdu, pdu_length); + + if (!rpch_in_send_CONN_B1(rpch)) + { + printf("rpch_out_send_CONN_A1 fault!\n"); + return false; + } + + status = rpch_out_read(rpch, pdu, pdu_length); + + /* [MS-RPCH] 3.2.1.5.3.1 Connection Establishment + * at this point VirtualChannel is created + */ + if (!rpch_in_send_bind(rpch)) + { + printf("rpch_out_send_bind fault!\n"); + return false; + } + + if (!rpch_out_recv_bind_ack(rpch)) + { + printf("rpch_out_recv_bind_ack fault!\n"); + return false; + } + + if (!rpch_in_send_rpc_auth_3(rpch)) + { + printf("rpch_out_send_rpc_auth_3 fault!\n"); + return false; + } + + xfree(pdu); + return true; +} + diff --git a/libfreerdp-core/rpch.h b/libfreerdp-core/rpch.h new file mode 100644 index 000000000..7db8ce11f --- /dev/null +++ b/libfreerdp-core/rpch.h @@ -0,0 +1,617 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __RPCH_H_ +#define __RPCH_H_ + +typedef struct rdp_rpch rdpRpch; +typedef struct rdp_rpch_http rdpRpchHTTP; + +#include "tcp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTYPE_REQUEST 0x00 +#define PTYPE_PING 0x01 +#define PTYPE_RESPONSE 0x02 +#define PTYPE_FAULT 0x03 +#define PTYPE_WORKING 0x04 +#define PTYPE_NOCALL 0x05 +#define PTYPE_REJECT 0x06 +#define PTYPE_ACK 0x07 +#define PTYPE_CL_CANCEL 0x08 +#define PTYPE_FACK 0x09 +#define PTYPE_CANCEL_ACK 0x0a +#define PTYPE_BIND 0x0b +#define PTYPE_BIND_ACK 0x0c +#define PTYPE_BIND_NAK 0x0d +#define PTYPE_ALTER_CONTEXT 0x0e +#define PTYPE_ALTER_CONTEXT_RESP 0x0f +#define PTYPE_RPC_AUTH_3 0x10 +#define PTYPE_SHUTDOWN 0x11 +#define PTYPE_CO_CANCEL 0x12 +#define PTYPE_ORPHANED 0x13 +#define PTYPE_RTS 0x14 + +#define PFC_FIRST_FRAG 0x01/* First fragment */ +#define PFC_LAST_FRAG 0x02/* Last fragment */ +#define PFC_PENDING_CANCEL 0x04/* Cancel was pending at sender */ +#define PFC_RESERVED_1 0x08 +#define PFC_CONC_MPX 0x10/* supports concurrent multiplexing + * of a single connection. */ +#define PFC_DID_NOT_EXECUTE 0x20/* only meaningful on `fault' packet; + * if true, guaranteed call did not + * execute. */ +#define PFC_MAYBE 0x40/* `maybe' call semantics requested */ +#define PFC_OBJECT_UUID 0x80/* if true, a non-nil object UUID + * was specified in the handle, and + * is present in the optional object + * field. If false, the object field + * is omitted. */ + +#define RTS_FLAG_NONE 0x0000 /*No special flags.*/ +#define RTS_FLAG_PING 0x0001 /*Proves that the sender is still active; can also be used to flush the pipeline by the other party.*/ +#define RTS_FLAG_OTHER_CMD 0x0002 /*Indicates that the PDU contains a command that cannot be defined by the other flags in this table.*/ +#define RTS_FLAG_RECYCLE_CHANNEL 0x0004 /*Indicates that the PDU is associated with recycling a channel.*/ +#define RTS_FLAG_IN_CHANNEL 0x0008 /*Indicates that the PDU is associated with IN channel communications.*/ +#define RTS_FLAG_OUT_CHANNEL 0x0010 /*Indicates that the PDU is associated with OUT channel communications.*/ +#define RTS_FLAG_EOF 0x0020 /*Indicates that this is the last PDU on an IN channel or OUT channel. Not all channels, however, use this to indicate the last PDU.*/ +#define RTS_FLAG_ECHO 0x0040 /*Signifies that this PDU is an echo request or response.*/ + +typedef uint16 p_context_id_t; + +typedef struct { + uuid if_uuid; + uint32 if_version; +} p_syntax_id_t; + +typedef struct { + p_context_id_t p_cont_id; + uint8 n_transfer_syn; /* number of items */ + uint8 reserved; /* alignment pad, m.b.z. */ + p_syntax_id_t abstract_syntax; /* transfer syntax list */ + p_syntax_id_t* transfer_syntaxes; /*size_is(n_transfer_syn)*/ +} p_cont_elem_t; + +typedef struct { + uint8 n_context_elem; /* number of items */ + uint8 reserved; /* alignment pad, m.b.z. */ + uint16 reserved2; /* alignment pad, m.b.z. */ + p_cont_elem_t* p_cont_elem; /*size_is(n_cont_elem)*/ +} p_cont_list_t; + +typedef enum { + acceptance, user_rejection, provider_rejection +} p_cont_def_result_t; + +typedef enum { + reason_not_specified, + abstract_syntax_not_supported, + proposed_transfer_syntaxes_not_supported, + local_limit_exceeded +} p_provider_reason_t; + + +typedef struct { + p_cont_def_result_t result; + p_provider_reason_t reason; /* only relevant if result != + * acceptance */ + p_syntax_id_t transfer_syntax;/* tr syntax selected + * 0 if result not + * accepted */ +} p_result_t; + +/* Same order and number of elements as in bind request */ + +typedef struct { + uint8 n_results; /* count */ + uint8 reserved; /* alignment pad, m.b.z. */ + uint16 reserved2; /* alignment pad, m.b.z. */ + p_result_t* p_results; /*size_is(n_results)*/ +} p_result_list_t; + +typedef struct { + uint8 major; + uint8 minor; +} version_t; +typedef version_t p_rt_version_t; + +typedef struct { + uint8 n_protocols; /* count */ + p_rt_version_t* p_protocols; /* size_is(n_protocols) */ +} p_rt_versions_supported_t; + +typedef struct { + uint16 length; + char* port_spec; /* port string spec; size_is(length) */ +} port_any_t; + +#define REASON_NOT_SPECIFIED 0 +#define TEMPORARY_CONGESTION 1 +#define LOCAL_LIMIT_EXCEEDED 2 +#define CALLED_PADDR_UNKNOWN 3 /* not used */ +#define PROTOCOL_VERSION_NOT_SUPPORTED 4 +#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ +#define USER_DATA_NOT_READABLE 6 /* not used */ +#define NO_PSAP_AVAILABLE 7 /* not used */ + +typedef uint16 rpcrt_reason_code_t;/* 0..65535 */ + +typedef struct { + uint8 rpc_vers; + uint8 rpc_vers_minor; + uint8 reserved[2];/* must be zero */ + uint8 packed_drep[4]; + uint32 reject_status; + uint8 reserved2[4]; +} rpcrt_optional_data_t; + +typedef struct { + rpcrt_reason_code_t reason_code; /* 0..65535 */ + rpcrt_optional_data_t rpc_info; /* may be RPC specific */ +} rpcconn_reject_optional_data_t; + +typedef struct { + rpcrt_reason_code_t reason_code; /* 0..65535 */ + rpcrt_optional_data_t rpc_info; /* may be RPC-specific */ +} rpcconn_disc_optional_data_t; + +typedef struct{ + /* restore 4 byte alignment */ + + uint8* auth_pad; /* align(4); size_is(auth_pad_length) */ + uint8 auth_type; /* :01 which authent service */ + uint8 auth_level; /* :01 which level within service */ + uint8 auth_pad_length; /* :01 */ + uint8 auth_reserved; /* :01 reserved, m.b.z. */ + uint32 auth_context_id; /* :04 */ + uint8* auth_value; /* credentials; size_is(auth_length) */ +} auth_verifier_co_t; + +/* Connection-oriented PDU Definitions */ + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor ; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 alter context PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + uint16 max_xmit_frag; /* ignored */ + uint16 max_recv_frag; /* ignored */ + uint32 assoc_group_id; /* ignored */ + + /* presentation context list */ + + p_cont_list_t p_context_elem; /* variable size */ + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; + +} rpcconn_alter_context_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 alter + context response PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + uint16 max_xmit_frag; /* ignored */ + uint16 max_recv_frag; /* ignored */ + uint32 assoc_group_id; /* ignored */ + port_any_t sec_addr; /* ignored */ + + /* restore 4-octet alignment */ + + uint8* pad2; /* size_is(align(4)) */ + + /* presentation context result list, including hints */ + + p_result_list_t p_result_list; /* variable size */ + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_alter_context_response_hdr_t; + +/* bind header */ +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 bind PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + uint16 max_xmit_frag; /* 16:02 max transmit frag size, bytes */ + uint16 max_recv_frag; /* 18:02 max receive frag size, bytes */ + uint32 assoc_group_id; /* 20:04 incarnation of client-server + * assoc group */ + /* presentation context list */ + + p_cont_list_t p_context_elem; /* variable size */ + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; +} rpcconn_bind_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor ; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 bind ack PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + uint16 max_xmit_frag; /* 16:02 max transmit frag size */ + uint16 max_recv_frag; /* 18:02 max receive frag size */ + uint32 assoc_group_id; /* 20:04 returned assoc_group_id */ + port_any_t sec_addr; /* 24:yy optional secondary address + * for process incarnation; local port + * part of address only */ + /* restore 4-octet alignment */ + + uint8* pad2; /* size_is(align(4)) */ + + /* presentation context result list, including hints */ + + p_result_list_t p_result_list; /* variable size */ + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_bind_ack_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor ; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 bind ack PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + uint16 max_xmit_frag; /* 16:02 max transmit frag size */ + uint16 max_recv_frag; /* 18:02 max receive frag size */ + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_rpc_auth_3_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor ; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 bind nak PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /*p_reject_reason_t*/uint16 provider_reject_reason; /* 16:02 presentation (TODO search definition of p_reject_reason_t) + context reject */ + + p_rt_versions_supported_t versions; /* 18:yy array of protocol + * versions supported */ +} rpcconn_bind_nak_hdr_t; + + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 CO cancel PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /* optional authentication verifier + * following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ + +} rpcconn_cancel_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 fault PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /* needed for request, response, fault */ + + uint32 alloc_hint; /* 16:04 allocation hint */ + p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ + + /* needed for response or fault */ + + uint8 cancel_count; /* 22:01 received cancel count */ + uint8 reserved; /* 23:01 reserved, m.b.z. */ + + /* fault code */ + + uint32 status; /* 24:04 run-time fault code or zero */ + + /* always pad to next 8-octet boundary */ + + uint8 reserved2[4]; /* 28:04 reserved padding, m.b.z. */ + + /* stub data here, 8-octet aligned + . + . + . */ + uint8* stub_data; + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_fault_hdr_t; + + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 orphaned PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /* optional authentication verifier + * following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_orphaned_hdr_t; + + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 request PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /* needed on request, response, fault */ + + uint32 alloc_hint; /* 16:04 allocation hint */ + p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ + uint16 opnum; /* 22:02 operation # + * within the interface */ + + /* optional field for request, only present if the PFC_OBJECT_UUID + * field is non-zero */ + + uuid object; /* 24:16 object UID */ + + /* stub data, 8-octet aligned + . + . + . */ + uint8* stub_data; + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_request_hdr_t; + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 response PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 length of auth_value */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ + + /* needed for request, response, fault */ + + uint32 alloc_hint; /* 16:04 allocation hint */ + p_context_id_t p_cont_id; /* 20:02 pres context, i.e. + * data rep */ + + /* needed for response or fault */ + + uint8 cancel_count; /* 22:01 cancel count */ + uint8 reserved; /* 23:01 reserved, m.b.z. */ + + /* stub data here, 8-octet aligned + . + . + . */ + uint8* stub_data; + + /* optional authentication verifier */ + /* following fields present iff auth_length != 0 */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_response_hdr_t; + + +typedef struct { + /* start 8-octet aligned */ + + /* common fields */ + uint8 rpc_vers; /* 00:01 RPC version */ + uint8 rpc_vers_minor; /* 01:01 minor version */ + uint8 PTYPE; /* 02:01 shutdown PDU */ + uint8 pfc_flags; /* 03:01 flags */ + uint8 packed_drep[4]; /* 04:04 NDR data rep format label*/ + uint16 frag_length; /* 08:02 total length of fragment */ + uint16 auth_length; /* 10:02 */ + uint32 call_id; /* 12:04 call identifier */ + + /* end common fields */ +} rpcconn_shutdown_hdr_t; + +/* proprietary stuff from Dmitrij Jasnov */ + +#define RPCH_HTTP_DISCONNECTED 0 +#define RPCH_HTTP_SENDING 1 +#define RPCH_HTTP_RECIEVING 2 + +struct rdp_rpch_http +{ + int state; + int contentLength; + int remContentLength; + //struct _NTLMSSP* ntht; +}; + +struct rdp_rpch +{ + struct rdp_settings* settings; + struct rdp_tcp* tcp_in; + struct rdp_tcp* tcp_out; + struct rdp_tls* tls_in; + struct rdp_tls* tls_out; + //struct _NTLMSSP* ntlmssp; + + struct rdp_rpch_http* http_in; + struct rdp_rpch_http* http_out; + + uint8* write_buffer; + uint32 write_buffer_len; + uint8* read_buffer; + uint32 read_buffer_len; + + uint32 BytesReceived; + uint32 AwailableWindow; + uint32 BytesSent; + uint32 RecAwailableWindow; + uint8* virtualConnectionCookie; + uint8* OUTChannelCookie; + uint8* INChannelCookie; + uint32 call_id; + uint32 pipe_call_id; +}; + + +rdpRpch* rpch_new(rdpSettings* settings); +boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); +boolean rpch_connect(rdpRpch* rpch); +int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum); +int rpch_read(rdpRpch* rpch, uint8* data, int length); + +#ifdef WITH_DEBUG_RPCH +#define DEBUG_RPCH(fmt, ...) DEBUG_CLASS(RPCH, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RPCH(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __RPCH_H_ */ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c new file mode 100644 index 000000000..d5de704c6 --- /dev/null +++ b/libfreerdp-core/tsg.c @@ -0,0 +1,273 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/*#include +#include +#include */ + +#include "tsg.h" + +boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) +{ + int status = -1; + + rdpRpch* rpch = tsg->rpch; + rdpTransport* transport = tsg->transport; + + uint32 length; + uint8* data; + + //if (!rpch_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) + if (!rpch_attach(rpch, NULL, NULL, NULL, NULL)) + { + printf("rpch_attach failed!\n"); + return false; + } + + if (!rpch_connect(rpch)) + { + printf("rpch_connect failed!\n"); + return false; + } + + uint8 p[108] = + { + 0x43, 0x56, 0x00, 0x00, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, 0x54, 0x43, 0x56, + 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB, + 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, + 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + }; + + status = rpch_write(rpch, p, 108, 1); + + if (status <= 0) + { + printf("rpch_write opnum=1 failed!\n"); + return false; + } + + length = 0x8FFF; + data = xmalloc(length); + status = rpch_read(rpch, data, length); + + if (status <= 0) + { + printf("rpch_recv failed!\n"); + return false; + } + + tsg->tunnelContext = xmalloc(16); + memcpy(tsg->tunnelContext, data + 0x91c, 16); + +#ifdef WITH_DEBUG_TSG + printf("TSG tunnelContext:\n"); + freerdp_hexdump(tsg->tunnelContext, 16); + printf("\n"); +#endif + + uint8 p2[112] = + { + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x52, 0x51, 0x00, 0x00, 0x52, 0x51, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, + 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + memcpy(p2 + 4, tsg->tunnelContext, 16); + + status = rpch_write(rpch, p2, 112, 2); + + if (status <= 0) + { + printf("rpch_write opnum=2 failed!\n"); + return false; + } + + status = rpch_read(rpch, data, length); + + if (status <= 0) + { + printf("rpch_recv failed!\n"); + return false; + } + + uint8 p3[40] = + { + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x01, 0x00, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 + }; + + memcpy(p3 + 4, tsg->tunnelContext, 16); + status = rpch_write(rpch, p3, 40, 3); + + if (status <= 0) + { + printf("rpch_write opnum=3 failed!\n"); + return false; + } + status = -1; + + UNICONV* tsg_uniconv = freerdp_uniconv_new(); + uint32 dest_addr_unic_len; + uint8* dest_addr_unic = (uint8*) freerdp_uniconv_out(tsg_uniconv, hostname, (size_t*) &dest_addr_unic_len); + freerdp_uniconv_free(tsg_uniconv); + + uint8 p4[48] = + { + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00 + }; + + memcpy(p4 + 4, tsg->tunnelContext, 16); + memcpy(p4 + 38, &port, 2); + + STREAM* s_p4 = stream_new(60 + dest_addr_unic_len + 2); + stream_write(s_p4, p4, 48); + stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1); /* MaximumCount */ + stream_write_uint32(s_p4, 0x00000000); /* Offset */ + stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1);/* ActualCount */ + stream_write(s_p4, dest_addr_unic, dest_addr_unic_len); + stream_write_uint16(s_p4,0x0000); /* unicode zero to terminate hostname string */ + + status = rpch_write(rpch, s_p4->data, s_p4->size, 4); + + if (status <= 0) + { + printf("rpch_write opnum=4 failed!\n"); + return false; + } + xfree(dest_addr_unic); + + status = rpch_read(rpch, data, length); + + if(status < 0) + { + printf("rpch_recv failed!\n"); + return false; + } + + tsg->channelContext = xmalloc(16); + memcpy(tsg->channelContext, data + 4, 16); + +#ifdef WITH_DEBUG_TSG + printf("TSG channelContext:\n"); + freerdp_hexdump(tsg->channelContext, 16); + printf("\n"); +#endif + + uint8 p5[20] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + memcpy(p5 + 4, tsg->channelContext, 16); + status = rpch_write(rpch, p5, 20, 8); + + if (status <= 0) + { + printf("rpch_write opnum=8 failed!\n"); + return false; + } + + return true; +} + +int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) +{ + int status = -1; + + uint16 opnum = 9; + uint32 tsg_length = length + 16 + 4 + 12 + 8; + uint32 totalDataBytes = length + 4; + + STREAM* s = stream_new(12); + stream_write_uint32_be(s,totalDataBytes); + stream_write_uint32_be(s,0x01); + stream_write_uint32_be(s,length); + + uint8* tsg_pkg = xmalloc(tsg_length); + memset(tsg_pkg, 0, 4); + memcpy(tsg_pkg + 4, tsg->channelContext, 16); + memcpy(tsg_pkg + 20, s->data, 12); + memcpy(tsg_pkg + 32, data, length); + + uint8 pp[8] = + { + 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + memcpy(tsg_pkg + 32 + length, pp, 8); + + status = rpch_write(tsg->rpch, tsg_pkg, tsg_length, opnum); + + xfree(tsg_pkg); + stream_free(s); + + if (status <= 0) + { + printf("rpch_write failed!\n"); + return -1; + } + + return length; +} + +int tsg_read(rdpTsg* tsg, uint* data, uint32 length) +{ + int status; + + status = rpch_read(tsg->rpch, data, length); + + return status; +} + +rdpTsg* tsg_new(rdpSettings* settings) +{ + rdpTsg* tsg; + tsg = (rdpTsg*) xzalloc(sizeof(rdpTsg)); + + tsg->settings = settings; + tsg->rpch = rpch_new(settings); + + return tsg; +} + +void tsg_free(rdpTsg* tsg) +{ + +} diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h new file mode 100644 index 000000000..36447ff6f --- /dev/null +++ b/libfreerdp-core/tsg.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSG_H_ +#define __TSG_H_ + +typedef struct rdp_tsg rdpTsg; + +#include "transport.h" +#include "rpch.h" + +#include +#include +#include +#include +#include +#include + +struct rdp_tsg +{ + struct rdp_settings* settings; + struct rdp_transport* transport; + struct rdp_rpch* rpch; + + uint8* tunnelContext; + uint8* channelContext; +}; + +boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port); +rdpTsg* tsg_new(rdpSettings* settings); +void tsg_free(rdpTsg* tsg); +int tsg_write(rdpTsg* tsg, uint8* data, uint32 length); +int tsg_read(rdpTsg* tsg, uint* data, uint32 length); + +#ifdef WITH_DEBUG_TSG +#define DEBUG_TSG(fmt, ...) DEBUG_CLASS(TSG, fmt, ## __VA_ARGS__) +#else +#define DEBUG_TSG(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __TSG_H_ */ diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp-crypto/crypto.c index 09b097a19..b01ebb2b3 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp-crypto/crypto.c @@ -511,3 +511,39 @@ void crypto_cert_print_info(X509* xcert) 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); +} + +void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length) +{ + BIO *b64, *bmem; + + *dec_data = xmalloc(length); + memset(*dec_data, 0, length); + + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + bmem = BIO_new_mem_buf(enc_data, length); + bmem = BIO_push(b64, bmem); + + *res_length = BIO_read(bmem, *dec_data, length); + + BIO_free_all(bmem); +} From 7e3c9331ad7705d6ffb7ea1fd5de7c99ff4e482b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 26 Mar 2012 03:04:47 -0400 Subject: [PATCH 02/47] libfreerdp-utils: add parsing of --tsg option --- include/freerdp/settings.h | 8 +++++--- libfreerdp-core/connection.c | 8 ++++++-- libfreerdp-utils/args.c | 28 +++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 3982aae32..bf099cb8f 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -278,9 +278,11 @@ struct rdp_settings rdpBlob* password_cookie; /* 61 */ char* kerberos_kdc; /* 62 */ char* kerberos_realm; /* 63 */ - char* tsg_hostname; /* 64 */ - char* tsg_password; /* 65 */ - uint32 paddingC[80 - 66]; /* 66 */ + boolean ts_gateway; /* 64 */ + char* tsg_hostname; /* 65 */ + char* tsg_username; /* 66 */ + char* tsg_password; /* 67 */ + uint32 paddingC[80 - 68]; /* 68 */ /* User Interface Parameters */ boolean sw_gdi; /* 80 */ diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index 86a724ddf..d285f54e2 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -69,8 +69,12 @@ boolean rdp_client_connect(rdpRdp* rdp) nego_set_target(rdp->nego, settings->hostname, settings->port); nego_set_cookie(rdp->nego, settings->username); nego_enable_rdp(rdp->nego, settings->rdp_security); - nego_enable_nla(rdp->nego, settings->nla_security); - nego_enable_tls(rdp->nego, settings->tls_security); + + if (!settings->ts_gateway) + { + nego_enable_nla(rdp->nego, settings->nla_security); + nego_enable_tls(rdp->nego, settings->tls_security); + } if (nego_connect(rdp->nego) != true) { diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index 9451421be..1696cd66a 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -101,11 +101,12 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, " --ntlm: force NTLM authentication protocol version (1 or 2)\n" " --ignore-certificate: ignore verification of logon certificate\n" " --sec: force protocol security (rdp, tls or nla)\n" + " --tsg: Terminal Server Gateway ( )\n" " --kbd-list: list all keyboard layout ids used by -k\n" " --salted-checksum: use salted checksums with Standard RDP encryption\n" " --version: print version information\n" "\n", argv[0]); - return FREERDP_ARGS_PARSE_HELP; //TODO: What is the correct return + return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */ } else if (strcmp("-a", argv[index]) == 0) { @@ -533,6 +534,31 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, return FREERDP_ARGS_PARSE_FAILURE; } } + else if (strcmp("--tsg", argv[index]) == 0) + { + settings->ts_gateway = true; + index++; + if (index == argc) + { + printf("missing TSG username\n"); + return -1; + } + settings->tsg_username = xstrdup(argv[index]); + index++; + if (index == argc) + { + printf("missing TSG password\n"); + return -1; + } + settings->tsg_password = xstrdup(argv[index]); + index++; + if (index == argc) + { + printf("missing TSG server\n"); + return -1; + } + settings->tsg_hostname = xstrdup(argv[index]); + } else if (strcmp("--plugin", argv[index]) == 0) { index++; From 1743a9464fbf7cb261ad867fd4e2f7ead95a2db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 26 Mar 2012 12:20:38 -0400 Subject: [PATCH 03/47] libfreerdp-core: add TSG to transport layer --- cmake/ConfigOptions.cmake | 1 + config.h.in | 1 + include/freerdp/utils/unicode.h | 2 +- libfreerdp-core/rpch.c | 5 +- libfreerdp-core/rpch.h | 49 +++++++------ libfreerdp-core/transport.c | 69 ++++++++++++++++-- libfreerdp-core/transport.h | 10 ++- libfreerdp-core/tsg.c | 119 ++++++++++++++++---------------- libfreerdp-core/tsg.h | 24 ++++--- libfreerdp-utils/unicode.c | 2 +- 10 files changed, 179 insertions(+), 103 deletions(-) diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 11c65b3f7..0e1951674 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -14,6 +14,7 @@ option(WITH_DEBUG_LICENSE "Print license debug messages." OFF) option(WITH_DEBUG_NEGO "Print negotiation related debug messages." OFF) option(WITH_DEBUG_NLA "Print authentication related debug messages." OFF) option(WITH_DEBUG_NTLM "Print NTLM debug messages" OFF) +option(WITH_DEBUG_TSG "Print Terminal Server Gateway debug messages" OFF) option(WITH_DEBUG_ORDERS "Print drawing orders debug messages" OFF) option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" OFF) option(WITH_DEBUG_RDP "Print RDP debug messages" OFF) diff --git a/config.h.in b/config.h.in index d250bedda..9b1f92599 100644 --- a/config.h.in +++ b/config.h.in @@ -37,6 +37,7 @@ #cmakedefine WITH_DEBUG_NEGO #cmakedefine WITH_DEBUG_NLA #cmakedefine WITH_DEBUG_NTLM +#cmakedefine WITH_DEBUG_TSG #cmakedefine WITH_DEBUG_ORDERS #cmakedefine WITH_DEBUG_RAIL #cmakedefine WITH_DEBUG_RDP diff --git a/include/freerdp/utils/unicode.h b/include/freerdp/utils/unicode.h index 7268a8ecb..0dabc9309 100644 --- a/include/freerdp/utils/unicode.h +++ b/include/freerdp/utils/unicode.h @@ -48,7 +48,7 @@ typedef struct _UNICONV UNICONV; FREERDP_API UNICONV* freerdp_uniconv_new(); FREERDP_API void freerdp_uniconv_free(UNICONV *uniconv); FREERDP_API char* freerdp_uniconv_in(UNICONV *uniconv, unsigned char* pin, size_t in_len); -FREERDP_API char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len); +FREERDP_API char* freerdp_uniconv_out(UNICONV *uniconv, const char *str, size_t *pout_len); FREERDP_API void freerdp_uniconv_uppercase(UNICONV *uniconv, char *wstr, int length); #endif /* __UNICODE_UTILS_H */ diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index be36dfa2f..7f103240e 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -1,8 +1,9 @@ /** * FreeRDP: A Remote Desktop Protocol Client - * RDP Security + * RPC over HTTP * - * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * Copyright 2012 Fujitsu Technology Solutions GmbH + * Copyright 2012 Dmitrij Jasnov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libfreerdp-core/rpch.h b/libfreerdp-core/rpch.h index 7db8ce11f..8f4b0c5de 100644 --- a/libfreerdp-core/rpch.h +++ b/libfreerdp-core/rpch.h @@ -1,8 +1,9 @@ /** * FreeRDP: A Remote Desktop Protocol Client - * RDP Security + * RPC over HTTP * - * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * Copyright 2012 Fujitsu Technology Solutions GmbH + * Copyright 2012 Dmitrij Jasnov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +18,8 @@ * limitations under the License. */ - -#ifndef __RPCH_H_ -#define __RPCH_H_ +#ifndef FREERDP_CORE_RPCH_H +#define FREERDP_CORE_RPCH_H typedef struct rdp_rpch rdpRpch; typedef struct rdp_rpch_http rdpRpchHTTP; @@ -559,15 +559,17 @@ typedef struct { /* end common fields */ } rpcconn_shutdown_hdr_t; -/* proprietary stuff from Dmitrij Jasnov */ - -#define RPCH_HTTP_DISCONNECTED 0 -#define RPCH_HTTP_SENDING 1 -#define RPCH_HTTP_RECIEVING 2 +enum _RPCH_HTTP_STATE +{ + RPCH_HTTP_DISCONNECTED = 0, + RPCH_HTTP_SENDING = 1, + RPCH_HTTP_RECIEVING = 2 +}; +typedef enum _RPCH_HTTP_STATE RPCH_HTTP_STATE; struct rdp_rpch_http { - int state; + RPCH_HTTP_STATE state; int contentLength; int remContentLength; //struct _NTLMSSP* ntht; @@ -575,15 +577,15 @@ struct rdp_rpch_http struct rdp_rpch { - struct rdp_settings* settings; - struct rdp_tcp* tcp_in; - struct rdp_tcp* tcp_out; - struct rdp_tls* tls_in; - struct rdp_tls* tls_out; + rdpSettings* settings; + rdpTcp* tcp_in; + rdpTcp* tcp_out; + rdpTls* tls_in; + rdpTls* tls_out; //struct _NTLMSSP* ntlmssp; - struct rdp_rpch_http* http_in; - struct rdp_rpch_http* http_out; + rdpRpchHTTP* http_in; + rdpRpchHTTP* http_out; uint8* write_buffer; uint32 write_buffer_len; @@ -601,17 +603,22 @@ struct rdp_rpch uint32 pipe_call_id; }; - -rdpRpch* rpch_new(rdpSettings* settings); boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); boolean rpch_connect(rdpRpch* rpch); + int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum); int rpch_read(rdpRpch* rpch, uint8* data, int length); +rdpRpch* rpch_new(rdpSettings* settings); + +#ifdef WITH_DEBUG_TSG +#define WITH_DEBUG_RPCH +#endif + #ifdef WITH_DEBUG_RPCH #define DEBUG_RPCH(fmt, ...) DEBUG_CLASS(RPCH, fmt, ## __VA_ARGS__) #else #define DEBUG_RPCH(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif -#endif /* __RPCH_H_ */ +#endif /* FREERDP_CORE_RPCH_H */ diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index 25acef876..a275ffb42 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -59,11 +59,6 @@ STREAM* transport_send_stream_init(rdpTransport* transport, int size) return s; } -boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port) -{ - return tcp_connect(transport->tcp, hostname, port); -} - void transport_attach(rdpTransport* transport, int sockfd) { transport->tcp->sockfd = sockfd; @@ -137,6 +132,61 @@ boolean transport_connect_nla(rdpTransport* transport) return true; } +boolean transport_tsg_connect(rdpTransport* transport, const char* hostname, uint16 port) +{ + rdpTsg* tsg = tsg_new(transport->settings); + + tsg->transport = transport; + transport->tsg = tsg; + + if (transport->tls_in == NULL) + transport->tls_in = tls_new(transport->settings); + + transport->tls_in->sockfd = transport->tcp_in->sockfd; + + if (transport->tls_out == NULL) + transport->tls_out = tls_new(transport->settings); + + transport->tls_out->sockfd = transport->tcp_out->sockfd; + + if (tls_connect(transport->tls_in) != true) + return false; + + if (tls_connect(transport->tls_out) != true) + return false; + + if (!tsg_connect(tsg, hostname, port)) + return false; + + return true; +} + +boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port) +{ + boolean status = false; + rdpSettings* settings = transport->settings; + + if (transport->settings->ts_gateway) + { + transport->layer = TRANSPORT_LAYER_TSG; + transport->tcp_out = tcp_new(settings); + + status = tcp_connect(transport->tcp_in, settings->tsg_hostname, 443); + + if (status) + status = tcp_connect(transport->tcp_out, settings->tsg_hostname, 443); + + if (status) + status = transport_tsg_connect(transport, hostname, port); + } + else + { + status = tcp_connect(transport->tcp, hostname, port); + } + + return status; +} + boolean transport_accept_rdp(rdpTransport* transport) { /* RDP encryption */ @@ -205,6 +255,8 @@ int transport_read(rdpTransport* transport, STREAM* s) status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s)); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s)); + else if (transport->layer == TRANSPORT_LAYER_TSG) + status = tsg_read(transport->tsg, stream_get_tail(s), stream_get_left(s)); if (status == 0 && transport->blocking) { @@ -263,6 +315,8 @@ int transport_write(rdpTransport* transport, STREAM* s) status = tls_write(transport->tls, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->tcp, stream_get_tail(s), length); + else if (transport->layer == TRANSPORT_LAYER_TSG) + status = tsg_write(transport->tsg, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ @@ -408,6 +462,8 @@ rdpTransport* transport_new(rdpSettings* settings) if (transport != NULL) { transport->tcp = tcp_new(settings); + transport->tcp_in = tcp_new(settings); + transport->settings = settings; /* a small 0.1ms delay when transport is blocking. */ @@ -437,9 +493,12 @@ void transport_free(rdpTransport* transport) stream_free(transport->recv_stream); stream_free(transport->send_stream); wait_obj_free(transport->recv_event); + if (transport->tls) tls_free(transport->tls); + tcp_free(transport->tcp); + xfree(transport); } } diff --git a/libfreerdp-core/transport.h b/libfreerdp-core/transport.h index d2a36680b..90693fbbe 100644 --- a/libfreerdp-core/transport.h +++ b/libfreerdp-core/transport.h @@ -24,12 +24,14 @@ typedef enum { TRANSPORT_LAYER_TCP, TRANSPORT_LAYER_TLS, + TRANSPORT_LAYER_TSG, TRANSPORT_LAYER_CLOSED } TRANSPORT_LAYER; typedef struct rdp_transport rdpTransport; #include "tcp.h" +#include "tsg.h" #include #include @@ -48,8 +50,13 @@ struct rdp_transport TRANSPORT_LAYER layer; struct rdp_tcp* tcp; struct rdp_tls* tls; - struct rdp_settings* settings; + struct rdp_tsg* tsg; + struct rdp_tcp* tcp_in; + struct rdp_tcp* tcp_out; + struct rdp_tls* tls_in; + struct rdp_tls* tls_out; struct rdp_credssp* credssp; + struct rdp_settings* settings; uint32 usleep_interval; void* recv_extra; STREAM* recv_buffer; @@ -66,6 +73,7 @@ boolean transport_disconnect(rdpTransport* transport); boolean transport_connect_rdp(rdpTransport* transport); boolean transport_connect_tls(rdpTransport* transport); boolean transport_connect_nla(rdpTransport* transport); +boolean transport_connect_tsg(rdpTransport* transport); boolean transport_accept_rdp(rdpTransport* transport); boolean transport_accept_tls(rdpTransport* transport); boolean transport_accept_nla(rdpTransport* transport); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index d5de704c6..5eff258bd 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -1,8 +1,9 @@ /** * FreeRDP: A Remote Desktop Protocol Client - * RDP Security + * Terminal Server Gateway (TSG) * - * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * Copyright 2012 Fujitsu Technology Solutions GmbH + * Copyright 2012 Dmitrij Jasnov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +19,7 @@ */ #include "config.h" + #include #include #include @@ -27,12 +29,50 @@ #include #include -/*#include -#include -#include */ - #include "tsg.h" +uint8 tsg_packet1[108] = +{ + 0x43, 0x56, 0x00, 0x00, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, 0x54, 0x43, 0x56, + 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB, + 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, + 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 +}; + +uint8 tsg_packet2[112] = +{ + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x52, 0x51, 0x00, 0x00, 0x52, 0x51, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, + 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 tsg_packet3[40] = +{ + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x01, 0x00, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 +}; + +uint8 tsg_packet4[48] = +{ + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00 +}; + +uint8 tsg_packet5[20] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { int status = -1; @@ -43,8 +83,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) uint32 length; uint8* data; - //if (!rpch_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) - if (!rpch_attach(rpch, NULL, NULL, NULL, NULL)) + if (!rpch_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) { printf("rpch_attach failed!\n"); return false; @@ -56,18 +95,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - uint8 p[108] = - { - 0x43, 0x56, 0x00, 0x00, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, 0x54, 0x43, 0x56, - 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB, - 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, - 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - - status = rpch_write(rpch, p, 108, 1); + status = rpch_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) { @@ -94,20 +122,9 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) printf("\n"); #endif - uint8 p2[112] = - { - 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, - 0x53, 0x6C, 0x04, 0x33, 0x52, 0x51, 0x00, 0x00, 0x52, 0x51, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, - 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; + memcpy(tsg_packet2 + 4, tsg->tunnelContext, 16); - memcpy(p2 + 4, tsg->tunnelContext, 16); - - status = rpch_write(rpch, p2, 112, 2); + status = rpch_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) { @@ -123,15 +140,8 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - uint8 p3[40] = - { - 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, - 0x53, 0x6C, 0x04, 0x33, 0x01, 0x00, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, 0x52, 0x47, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 - }; - - memcpy(p3 + 4, tsg->tunnelContext, 16); - status = rpch_write(rpch, p3, 40, 3); + memcpy(tsg_packet3 + 4, tsg->tunnelContext, 16); + status = rpch_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); if (status <= 0) { @@ -145,18 +155,11 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) uint8* dest_addr_unic = (uint8*) freerdp_uniconv_out(tsg_uniconv, hostname, (size_t*) &dest_addr_unic_len); freerdp_uniconv_free(tsg_uniconv); - uint8 p4[48] = - { - 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, - 0x53, 0x6C, 0x04, 0x33, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00 - }; - - memcpy(p4 + 4, tsg->tunnelContext, 16); - memcpy(p4 + 38, &port, 2); + memcpy(tsg_packet4 + 4, tsg->tunnelContext, 16); + memcpy(tsg_packet4 + 38, &port, 2); STREAM* s_p4 = stream_new(60 + dest_addr_unic_len + 2); - stream_write(s_p4, p4, 48); + stream_write(s_p4, tsg_packet4, 48); stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1); /* MaximumCount */ stream_write_uint32(s_p4, 0x00000000); /* Offset */ stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1);/* ActualCount */ @@ -189,14 +192,8 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) printf("\n"); #endif - uint8 p5[20] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - memcpy(p5 + 4, tsg->channelContext, 16); - status = rpch_write(rpch, p5, 20, 8); + memcpy(tsg_packet5 + 4, tsg->channelContext, 16); + status = rpch_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) { @@ -247,7 +244,7 @@ int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) return length; } -int tsg_read(rdpTsg* tsg, uint* data, uint32 length) +int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) { int status; diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 36447ff6f..f8522af7d 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -1,8 +1,9 @@ /** * FreeRDP: A Remote Desktop Protocol Client - * RDP Security + * Terminal Server Gateway (TSG) * - * Copyright 2012 Fujitsu Technology Solutions GmbH - Dmitrij Jasnov + * Copyright 2012 Fujitsu Technology Solutions GmbH + * Copyright 2012 Dmitrij Jasnov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +18,8 @@ * limitations under the License. */ -#ifndef __TSG_H_ -#define __TSG_H_ +#ifndef FREERDP_CORE_TSG_H +#define FREERDP_CORE_TSG_H typedef struct rdp_tsg rdpTsg; @@ -34,19 +35,20 @@ typedef struct rdp_tsg rdpTsg; struct rdp_tsg { - struct rdp_settings* settings; - struct rdp_transport* transport; - struct rdp_rpch* rpch; - + rdpRpch* rpch; uint8* tunnelContext; uint8* channelContext; + rdpSettings* settings; + rdpTransport* transport; }; boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port); + +int tsg_write(rdpTsg* tsg, uint8* data, uint32 length); +int tsg_read(rdpTsg* tsg, uint8* data, uint32 length); + rdpTsg* tsg_new(rdpSettings* settings); void tsg_free(rdpTsg* tsg); -int tsg_write(rdpTsg* tsg, uint8* data, uint32 length); -int tsg_read(rdpTsg* tsg, uint* data, uint32 length); #ifdef WITH_DEBUG_TSG #define DEBUG_TSG(fmt, ...) DEBUG_CLASS(TSG, fmt, ## __VA_ARGS__) @@ -54,4 +56,4 @@ int tsg_read(rdpTsg* tsg, uint* data, uint32 length); #define DEBUG_TSG(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif -#endif /* __TSG_H_ */ +#endif /* FREERDP_CORE_TSG_H */ diff --git a/libfreerdp-utils/unicode.c b/libfreerdp-utils/unicode.c index 6524a35ad..960d2360d 100644 --- a/libfreerdp-utils/unicode.c +++ b/libfreerdp-utils/unicode.c @@ -98,7 +98,7 @@ char* freerdp_uniconv_in(UNICONV* uniconv, unsigned char* pin, size_t in_len) /* Convert str from DEFAULT_CODEPAGE to WINDOWS_CODEPAGE and return buffer like xstrdup. * Buffer is 0-terminated but that is not included in the returned length. */ -char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len) +char* freerdp_uniconv_out(UNICONV* uniconv, const char *str, size_t* pout_len) { size_t ibl; size_t obl; From 809cc99b82051b4ec670042aec5680a47e6cafb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 26 Mar 2012 23:20:25 -0400 Subject: [PATCH 04/47] libfreerdp-core: start TSG integration with libfreerdp-sspi --- libfreerdp-core/rpch.c | 253 +++++++++++++++++++++++++++++++---------- libfreerdp-core/rpch.h | 39 ++++++- 2 files changed, 229 insertions(+), 63 deletions(-) diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index 7f103240e..5de75ec0c 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -29,37 +29,6 @@ #define HTTP_STREAM_SIZE 0xFFFF -rdpRpch* rpch_new(rdpSettings* settings) -{ - rdpRpch* rpch; - rpch = (rdpRpch*) xzalloc(sizeof(rdpRpch)); - - rpch->http_in = (rdpRpchHTTP*) xzalloc(sizeof(rdpRpchHTTP)); - rpch->http_out = (rdpRpchHTTP*) xzalloc(sizeof(rdpRpchHTTP)); - - //rpch->http_in->ntht = ntlmssp_client_new(); - //rpch->http_out->ntht = ntlmssp_client_new(); - rpch->http_in->state = RPCH_HTTP_DISCONNECTED; - rpch->http_out->state = RPCH_HTTP_DISCONNECTED; - - rpch->read_buffer = NULL; - rpch->write_buffer = NULL; - rpch->read_buffer_len = 0; - rpch->write_buffer_len = 0; - - rpch->BytesReceived = 0; - rpch->AwailableWindow = 0; - rpch->BytesSent = 0; - rpch->RecAwailableWindow = 0; - - rpch->settings = settings; - - //rpch->ntlmssp = ntlmssp_client_new(); - - rpch->call_id = 0; - return rpch; -} - boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out) { rpch->tcp_in = tcp_in; @@ -70,39 +39,170 @@ boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_ return true; } +#define NTLM_PACKAGE_NAME _T("NTLM") + +boolean ntlm_client_init(rdpNtlm* ntlm, char* user, char* domain, char* password) +{ + size_t size; + SECURITY_STATUS status; + + sspi_GlobalInit(); + + ntlm->table = InitSecurityInterface(); + + ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + + ntlm->identity.User = (uint16*) freerdp_uniconv_out(ntlm->uniconv, user, &size); + ntlm->identity.UserLength = (uint32) size; + + if (domain) + { + ntlm->identity.Domain = (uint16*) freerdp_uniconv_out(ntlm->uniconv, domain, &size); + ntlm->identity.DomainLength = (uint32) size; + } + else + { + ntlm->identity.Domain = (uint16*) NULL; + ntlm->identity.DomainLength = 0; + } + + ntlm->identity.Password = (uint16*) freerdp_uniconv_out(ntlm->uniconv, (char*) password, &size); + ntlm->identity.PasswordLength = (uint32) size; + + status = QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo); + + if (status != SEC_E_OK) + { + printf("QuerySecurityPackageInfo status: 0x%08X\n", status); + return false; + } + + ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken; + + status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME, + SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration); + + if (status != SEC_E_OK) + { + printf("AcquireCredentialsHandle status: 0x%08X\n", status); + return false; + } + + ntlm->haveContext = false; + ntlm->haveInputBuffer = false; + memset(&ntlm->inputBuffer, 0, sizeof(SecBuffer)); + memset(&ntlm->outputBuffer, 0, sizeof(SecBuffer)); + memset(&ntlm->ContextSizes, 0, sizeof(SecPkgContext_Sizes)); + + ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | + ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE; + + return true; +} + +boolean ntlm_authenticate(rdpNtlm* ntlm) +{ + SECURITY_STATUS status; + + ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION; + ntlm->outputBufferDesc.cBuffers = 1; + ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer; + ntlm->outputBuffer.BufferType = SECBUFFER_TOKEN; + ntlm->outputBuffer.cbBuffer = ntlm->cbMaxToken; + ntlm->outputBuffer.pvBuffer = xmalloc(ntlm->outputBuffer.cbBuffer); + + status = ntlm->table->InitializeSecurityContext(&ntlm->credentials, + (ntlm->haveContext) ? &ntlm->context : NULL, + NULL, ntlm->fContextReq, 0, SECURITY_NATIVE_DREP, + (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL, + 0, &ntlm->context, &ntlm->outputBufferDesc, + &ntlm->pfContextAttr, &ntlm->expiration); + + if (ntlm->inputBuffer.pvBuffer != NULL) + { + xfree(ntlm->inputBuffer.pvBuffer); + ntlm->inputBuffer.pvBuffer = NULL; + } + + if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) + { + if (ntlm->table->CompleteAuthToken != NULL) + ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc); + + if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK) + { + printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); + return 0; + } + + if (status == SEC_I_COMPLETE_NEEDED) + status = SEC_E_OK; + else if (status == SEC_I_COMPLETE_AND_CONTINUE) + status = SEC_I_CONTINUE_NEEDED; + } + + ntlm->haveInputBuffer = true; + ntlm->haveContext = true; + + return true; +} + +void ntlm_client_uninit(rdpNtlm* ntlm) +{ + FreeCredentialsHandle(&ntlm->credentials); + FreeContextBuffer(ntlm->pPackageInfo); +} + +rdpNtlm* ntlm_new() +{ + rdpNtlm* ntlm = xnew(rdpNtlm); + + if (ntlm != NULL) + { + ntlm->uniconv = freerdp_uniconv_new(); + } + + return ntlm; +} + +void ntlm_free(rdpNtlm* ntlm) +{ + if (ntlm != NULL) + { + freerdp_uniconv_free(ntlm->uniconv); + } +} + boolean rpch_out_connect_http(rdpRpch* rpch) { + STREAM* http_stream; + STREAM* ntlm_stream; + int decoded_ntht_length; + int encoded_ntht_length; + uint8* decoded_ntht_data = NULL; + uint8* encoded_ntht_data = NULL; rdpTls* tls_out = rpch->tls_out; rdpSettings* settings = rpch->settings; rdpRpchHTTP* http_out = rpch->http_out; - //NTLMSSP* http_out_ntlmssp = http_out->ntht; + rdpNtlm* http_out_ntlm = http_out->ntlm; - STREAM* ntlmssp_stream; - STREAM* http_stream; - - ntlmssp_stream = stream_new(0xFFFF); http_stream = stream_new(0xFFFF); + ntlm_stream = stream_new(0xFFFF); - uint8* decoded_ntht_data = NULL; - int decoded_ntht_length; - uint8* encoded_ntht_data = NULL; - int encoded_ntht_length; + printf("rpch_out_connect_http\n"); - //ntlmssp_set_username(http_out_ntlmssp, settings->username); - //ntlmssp_set_password(http_out_ntlmssp, settings->password); - //ntlmssp_set_domain(http_out_ntlmssp, settings->domain); - //ntlmssp_set_workstation(http_out_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ + ntlm_client_init(http_out_ntlm, settings->username, settings->password, settings->domain); - //ntlmssp_send(http_out_ntlmssp, ntlmssp_stream); + ntlm_authenticate(http_out_ntlm); + ntlm_stream->size = http_out_ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = http_out_ntlm->outputBuffer.pvBuffer; - decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_length = ntlm_stream->size; decoded_ntht_data = xmalloc(decoded_ntht_length); + stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; - stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); - - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_clear(ntlm_stream); + ntlm_stream->p = ntlm_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); @@ -205,25 +305,25 @@ boolean rpch_out_connect_http(rdpRpch* rpch) crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); - stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_write(ntlm_stream, decoded_ntht_data, decoded_ntht_length); + ntlm_stream->p = ntlm_stream->data; xfree(decoded_ntht_data); xfree(encoded_ntht_data); //ntlmssp_recv(http_out_ntlmssp, ntlmssp_stream); - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_clear(ntlm_stream); + ntlm_stream->p = ntlm_stream->data; //ntlmssp_send(http_out_ntlmssp, ntlmssp_stream); - decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_length = ntlm_stream->p-ntlm_stream->data; decoded_ntht_data = xmalloc(decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; - stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + ntlm_stream->p = ntlm_stream->data; + stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_clear(ntlm_stream); + ntlm_stream->p = ntlm_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); @@ -1396,3 +1496,36 @@ boolean rpch_connect(rdpRpch* rpch) return true; } +rdpRpch* rpch_new(rdpSettings* settings) +{ + rdpRpch* rpch = (rdpRpch*) xnew(rdpRpch); + + if (rpch != NULL) + { + rpch->http_in = (rdpRpchHTTP*) xnew(rdpRpchHTTP); + rpch->http_out = (rdpRpchHTTP*) xnew(rdpRpchHTTP); + + rpch->http_in->ntlm = ntlm_new(); + rpch->http_out->ntlm = ntlm_new(); + rpch->http_in->state = RPCH_HTTP_DISCONNECTED; + rpch->http_out->state = RPCH_HTTP_DISCONNECTED; + + rpch->read_buffer = NULL; + rpch->write_buffer = NULL; + rpch->read_buffer_len = 0; + rpch->write_buffer_len = 0; + + rpch->BytesReceived = 0; + rpch->AwailableWindow = 0; + rpch->BytesSent = 0; + rpch->RecAwailableWindow = 0; + + rpch->settings = settings; + + rpch->ntlm = ntlm_new(); + + rpch->call_id = 0; + } + + return rpch; +} diff --git a/libfreerdp-core/rpch.h b/libfreerdp-core/rpch.h index 8f4b0c5de..9e40e18c4 100644 --- a/libfreerdp-core/rpch.h +++ b/libfreerdp-core/rpch.h @@ -559,6 +559,29 @@ typedef struct { /* end common fields */ } rpcconn_shutdown_hdr_t; +struct rdp_ntlm +{ + UNICONV* uniconv; + CtxtHandle context; + uint32 cbMaxToken; + uint32 fContextReq; + uint32 pfContextAttr; + TimeStamp expiration; + PSecBuffer pBuffer; + SecBuffer inputBuffer; + SecBuffer outputBuffer; + boolean haveContext; + boolean haveInputBuffer; + SecBufferDesc inputBufferDesc; + SecBufferDesc outputBufferDesc; + CredHandle credentials; + SecPkgInfo* pPackageInfo; + SecurityFunctionTable* table; + SEC_WINNT_AUTH_IDENTITY identity; + SecPkgContext_Sizes ContextSizes; +}; +typedef struct rdp_ntlm rdpNtlm; + enum _RPCH_HTTP_STATE { RPCH_HTTP_DISCONNECTED = 0, @@ -572,21 +595,23 @@ struct rdp_rpch_http RPCH_HTTP_STATE state; int contentLength; int remContentLength; - //struct _NTLMSSP* ntht; + rdpNtlm* ntlm; }; struct rdp_rpch { - rdpSettings* settings; rdpTcp* tcp_in; rdpTcp* tcp_out; rdpTls* tls_in; rdpTls* tls_out; - //struct _NTLMSSP* ntlmssp; + rdpNtlm* ntlm; rdpRpchHTTP* http_in; rdpRpchHTTP* http_out; + UNICONV* uniconv; + rdpSettings* settings; + uint8* write_buffer; uint32 write_buffer_len; uint8* read_buffer; @@ -603,6 +628,14 @@ struct rdp_rpch uint32 pipe_call_id; }; +boolean ntlm_authenticate(rdpNtlm* ntlm); + +boolean ntlm_client_init(rdpNtlm* ntlm, char* user, char* domain, char* password); +void ntlm_client_uninit(rdpNtlm* ntlm); + +rdpNtlm* ntlm_new(); +void ntlm_free(rdpNtlm* ntlm); + boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); boolean rpch_connect(rdpRpch* rpch); From dcf6c3dc6413eaf5279de4b266b71a935dd9e17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 28 Mar 2012 10:34:23 -0400 Subject: [PATCH 05/47] libfreerdp-core: continue NTLM integration with TSG --- libfreerdp-core/rpch.c | 114 ++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index 5de75ec0c..4f7507745 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -281,11 +281,11 @@ boolean rpch_out_connect_http(rdpRpch* rpch) } } - if (*(http_stream->p-1) == '\n' && *(http_stream->p-3) == '\n') + if (*(http_stream->p - 1) == '\n' && *(http_stream->p - 3) == '\n') { int i; - for(i = 0; i < http_out->contentLength; i++) + for (i = 0; i < http_out->contentLength; i++) { tls_read(tls_out, &buffer_byte, 1); stream_write(http_stream, &buffer_byte, 1); @@ -311,15 +311,16 @@ boolean rpch_out_connect_http(rdpRpch* rpch) xfree(decoded_ntht_data); xfree(encoded_ntht_data); - //ntlmssp_recv(http_out_ntlmssp, ntlmssp_stream); + http_out_ntlm->inputBuffer.pvBuffer = ntlm_stream->data; + http_out_ntlm->inputBuffer.cbBuffer = ntlm_stream->size; + + ntlm_authenticate(http_out_ntlm); stream_clear(ntlm_stream); - ntlm_stream->p = ntlm_stream->data; + ntlm_stream->size = http_out_ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = http_out_ntlm->outputBuffer.pvBuffer; - //ntlmssp_send(http_out_ntlmssp, ntlmssp_stream); - - decoded_ntht_length = ntlm_stream->p-ntlm_stream->data; + decoded_ntht_length = ntlm_stream->size; decoded_ntht_data = xmalloc(decoded_ntht_length); - ntlm_stream->p = ntlm_stream->data; stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); stream_clear(ntlm_stream); @@ -362,37 +363,34 @@ boolean rpch_out_connect_http(rdpRpch* rpch) boolean rpch_in_connect_http(rdpRpch* rpch) { + STREAM* ntlm_stream; + STREAM* http_stream; + int decoded_ntht_length; + int encoded_ntht_length; + uint8* decoded_ntht_data = NULL; + uint8* encoded_ntht_data = NULL; rdpTls* tls_in = rpch->tls_in; rdpSettings* settings = rpch->settings; rdpRpchHTTP* http_in = rpch->http_in; - //NTLMSSP* http_in_ntlmssp = http_in->ntht; + rdpNtlm* http_in_ntlm = http_in->ntlm; - STREAM* ntlmssp_stream; - STREAM* http_stream; - - ntlmssp_stream = stream_new(0xFFFF); + ntlm_stream = stream_new(0xFFFF); http_stream = stream_new(0xFFFF); - uint8* decoded_ntht_data = NULL; - int decoded_ntht_length; - uint8* encoded_ntht_data = NULL; - int encoded_ntht_length; + ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); - //ntlmssp_set_username(http_in_ntlmssp, settings->username); - //ntlmssp_set_password(http_in_ntlmssp, settings->password); - //ntlmssp_set_domain(http_in_ntlmssp, settings->domain); - //ntlmssp_set_workstation(http_in_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ + ntlm_authenticate(http_in_ntlm); + ntlm_stream->size = http_in_ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = http_in_ntlm->outputBuffer.pvBuffer; - //ntlmssp_send(http_in_ntlmssp,ntlmssp_stream); - - decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_length = ntlm_stream->p - ntlm_stream->data; decoded_ntht_data = xmalloc(decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; - stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + ntlm_stream->p = ntlm_stream->data; + stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_clear(ntlm_stream); + ntlm_stream->p = ntlm_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); @@ -495,25 +493,26 @@ boolean rpch_in_connect_http(rdpRpch* rpch) crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); - stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_write(ntlm_stream, decoded_ntht_data, decoded_ntht_length); + ntlm_stream->p = ntlm_stream->data; xfree(decoded_ntht_data); xfree(encoded_ntht_data); - //ntlmssp_recv(http_in_ntlmssp, ntlmssp_stream); - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + http_in_ntlm->inputBuffer.pvBuffer = ntlm_stream->data; + http_in_ntlm->inputBuffer.cbBuffer = ntlm_stream->size; - //ntlmssp_send(http_in_ntlmssp, ntlmssp_stream); + ntlm_authenticate(http_in_ntlm); + stream_clear(ntlm_stream); + ntlm_stream->size = http_in_ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = http_in_ntlm->outputBuffer.pvBuffer; - decoded_ntht_length = ntlmssp_stream->p-ntlmssp_stream->data; + decoded_ntht_length = ntlm_stream->size; decoded_ntht_data = xmalloc(decoded_ntht_length); - ntlmssp_stream->p = ntlmssp_stream->data; - stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); + stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - stream_clear(ntlmssp_stream); - ntlmssp_stream->p = ntlmssp_stream->data; + stream_clear(ntlm_stream); + ntlm_stream->p = ntlm_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); @@ -558,8 +557,10 @@ int rpch_out_write(rdpRpch* rpch, uint8* data, int length) rdpTls* tls_out = rpch->tls_out; if (http_out->state == RPCH_HTTP_DISCONNECTED) + { if (!rpch_out_connect_http(rpch)) return false; + } if (http_out->remContentLength < length) { @@ -596,8 +597,10 @@ int rpch_in_write(rdpRpch* rpch, uint8* data, int length) rdpTls* tls_in = rpch->tls_in; if (http_in->state == RPCH_HTTP_DISCONNECTED) + { if (!rpch_in_connect_http(rpch)) return -1; + } if (http_in->remContentLength < length) { @@ -629,7 +632,7 @@ int rpch_in_write(rdpRpch* rpch, uint8* data, int length) uint8* rpch_create_cookie() { - uint8 *ret = xmalloc(16); + uint8* ret = xmalloc(16); RAND_pseudo_bytes(ret, 16); return ret; } @@ -801,25 +804,30 @@ boolean rpch_in_send_keep_alive(rdpRpch* rpch) boolean rpch_in_send_bind(rdpRpch* rpch) { + rdpSettings* settings = rpch->settings; STREAM* ntlm_stream = stream_new(0xFFFF); - //rpch->ntlmssp = ntlmssp_client_new(); - //rpch->ntlmssp->ntlm_v2 = true; - //rpch->ntlmssp->do_not_seal = true; - //ntlmssp_set_username(rpch->ntlmssp, "PanoGatewayUser49"); - //ntlmssp_set_password(rpch->ntlmssp, rpch->settings->tsg_password); - //ntlmssp_set_domain(rpch->ntlmssp, "PANOGATEWAY"); - //ntlmssp_set_workstation(rpch->ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ - //ntlmssp_send(rpch->ntlmssp,ntlm_stream); + /* TODO: Set NTLMv2 + DO_NOT_SEAL, DomainName = GatewayName? */ + + rpch->ntlm = ntlm_new(); + + ntlm_client_init(rpch->ntlm, settings->username, settings->password, settings->domain); + + ntlm_authenticate(rpch->ntlm); + ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; rpcconn_bind_hdr_t* bind_pdu = xmalloc(sizeof(rpcconn_bind_hdr_t)); bind_pdu->rpc_vers = 5; bind_pdu->rpc_vers_minor = 0; bind_pdu->PTYPE = PTYPE_BIND; bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX; - bind_pdu->packed_drep[0] = 0x10;bind_pdu->packed_drep[1] = 0x00;bind_pdu->packed_drep[2] = 0x00;bind_pdu->packed_drep[3] = 0x00; + bind_pdu->packed_drep[0] = 0x10; + bind_pdu->packed_drep[1] = 0x00; + bind_pdu->packed_drep[2] = 0x00; + bind_pdu->packed_drep[3] = 0x00; bind_pdu->frag_length = 124 + (ntlm_stream->p - ntlm_stream->data); - bind_pdu->auth_length = ntlm_stream->p - ntlm_stream->data; + bind_pdu->auth_length = ntlm_stream->size; bind_pdu->call_id = 2; bind_pdu->max_xmit_frag = 0x0FF8; bind_pdu->max_recv_frag = 0x0FF8; @@ -922,7 +930,9 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) { STREAM* ntlm_stream = stream_new(0xFFFF); - //ntlmssp_send(rpch->ntlmssp,ntlm_stream); + ntlm_authenticate(rpch->ntlm); + ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu = xmalloc(sizeof(rpcconn_rpc_auth_3_hdr_t)); rpc_auth_3_pdu->rpc_vers = 5; @@ -934,7 +944,7 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) rpc_auth_3_pdu->packed_drep[2] = 0x00; rpc_auth_3_pdu->packed_drep[3] = 0x00; rpc_auth_3_pdu->frag_length = 28 + (ntlm_stream->p - ntlm_stream->data); - rpc_auth_3_pdu->auth_length = ntlm_stream->p - ntlm_stream->data; + rpc_auth_3_pdu->auth_length = ntlm_stream->size; rpc_auth_3_pdu->call_id = 2; rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; rpc_auth_3_pdu->max_recv_frag = 0x0FF8; From 57fbe60d3387359fe81eb8048f30894c644e8cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 28 Mar 2012 13:14:18 -0400 Subject: [PATCH 06/47] libfreerdp-core: add extra debug output for TSG integration --- libfreerdp-core/rpch.c | 222 ++++++++++++++++++++--------------------- libfreerdp-core/tsg.c | 2 + 2 files changed, 113 insertions(+), 111 deletions(-) diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index 4f7507745..23e1570d7 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -277,7 +277,7 @@ boolean rpch_out_connect_http(rdpRpch* rpch) i++; } - http_out->contentLength = strtol((char*)(http_stream->p-i),NULL,10); + http_out->contentLength = strtol((char*)(http_stream->p - i), NULL, 10); } } @@ -641,6 +641,8 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) { STREAM* pdu = stream_new(76); + DEBUG_RPCH("Sending CONN_A1"); + uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; uint8 ptype = PTYPE_RTS; @@ -651,23 +653,16 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) uint32 call_id = 0x00000000; uint16 flags = 0x0000; uint16 num_commands = 0x0004; - - /* Version */ uint32 vCommandType = 0x00000006; uint32 Version = 0x00000001; - - /* VirtualConnectionCookie */ uint32 vccCommandType = 0x00000003; - rpch->virtualConnectionCookie = rpch_create_cookie(); /* 16 bytes */ - - /* OUTChannelCookie */ uint32 occCommandType = 0x00000003; - rpch->OUTChannelCookie = rpch_create_cookie(); /* 16 bytes */ - - /* ReceiveWindowSize */ uint32 rwsCommandType = 0x00000000; - uint32 reseiveWindowSize = 0x00010000; - rpch->AwailableWindow = reseiveWindowSize; + uint32 receiveWindowSize = 0x00010000; + + rpch->virtualConnectionCookie = rpch_create_cookie(); /* 16 bytes */ + rpch->OUTChannelCookie = rpch_create_cookie(); /* 16 bytes */ + rpch->AwailableWindow = receiveWindowSize; stream_write_uint8(pdu, rpc_vers); stream_write_uint8(pdu, rpc_vers_minor); @@ -686,9 +681,9 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) stream_write_uint32(pdu, occCommandType); stream_write(pdu, rpch->OUTChannelCookie, 16); stream_write_uint32(pdu, rwsCommandType); - stream_write_uint32(pdu, reseiveWindowSize); + stream_write_uint32(pdu, receiveWindowSize); - rpch_out_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_out_write(rpch, pdu->data, stream_get_length(pdu)); stream_free(pdu); @@ -699,6 +694,8 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) { STREAM* pdu = stream_new(104); + DEBUG_RPCH("Sending CONN_B1"); + uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; uint8 ptype = PTYPE_RTS; @@ -709,29 +706,19 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) uint32 call_id = 0x00000000; uint16 flags = 0x0000; uint16 num_commands = 0x0006; - - /* Version */ uint32 vCommandType = 0x00000006; uint32 Version = 0x00000001; - - /* VirtualConnectionCookie */ uint32 vccCommandType = 0x00000003; - - /* INChannelCookie */ uint32 iccCommandType = 0x00000003; - rpch->INChannelCookie = rpch_create_cookie(); /* 16bytes */ - - /* ChannelLifetime */ uint32 clCommandType = 0x00000004; uint32 ChannelLifetime = 0x40000000; - - /* ClientKeepalive */ uint32 ckCommandType = 0x00000005; uint32 ClientKeepalive = 0x000493e0; - - /* AssociationGroupId */ uint32 agidCommandType = 0x0000000c; - uint8* AssociationGroupId = rpch_create_cookie(); /* 16 bytes */ + uint8* AssociationGroupId; + + rpch->INChannelCookie = rpch_create_cookie(); /* 16bytes */ + AssociationGroupId = rpch_create_cookie(); /* 16 bytes */ stream_write_uint8(pdu, rpc_vers); stream_write_uint8(pdu, rpc_vers_minor); @@ -756,7 +743,7 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) stream_write_uint32(pdu, agidCommandType); stream_write(pdu, AssociationGroupId, 16); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); stream_free(pdu); @@ -765,7 +752,7 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) boolean rpch_in_send_keep_alive(rdpRpch* rpch) { - STREAM* pdu = stream_new(28); + STREAM* s = stream_new(28); uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; @@ -777,33 +764,32 @@ boolean rpch_in_send_keep_alive(rdpRpch* rpch) uint32 call_id = 0x00000000; uint16 flags = 0x0002; uint16 num_commands = 0x0001; - - /* ClientKeepalive */ uint32 ckCommandType = 0x00000005; uint32 ClientKeepalive = 0x00007530; - stream_write_uint8(pdu, rpc_vers); - stream_write_uint8(pdu, rpc_vers_minor); - stream_write_uint8(pdu, ptype); - stream_write_uint8(pdu, pfc_flags); - stream_write_uint32(pdu, packet_drep); - stream_write_uint16(pdu, frag_length); - stream_write_uint16(pdu, auth_length); - stream_write_uint32(pdu, call_id); - stream_write_uint16(pdu, flags); - stream_write_uint16(pdu, num_commands); - stream_write_uint32(pdu, ckCommandType); - stream_write_uint32(pdu, ClientKeepalive); + 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); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_in_write(rpch, s->data, stream_get_length(s)); - stream_free(pdu); + stream_free(s); return true; } boolean rpch_in_send_bind(rdpRpch* rpch) { + rpcconn_bind_hdr_t* bind_pdu; rdpSettings* settings = rpch->settings; STREAM* ntlm_stream = stream_new(0xFFFF); @@ -811,13 +797,15 @@ boolean rpch_in_send_bind(rdpRpch* rpch) rpch->ntlm = ntlm_new(); + DEBUG_RPCH("TODO: complete NTLM integration"); + ntlm_client_init(rpch->ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(rpch->ntlm); ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; - rpcconn_bind_hdr_t* bind_pdu = xmalloc(sizeof(rpcconn_bind_hdr_t)); + bind_pdu = xnew(rpcconn_bind_hdr_t); bind_pdu->rpc_vers = 5; bind_pdu->rpc_vers_minor = 0; bind_pdu->PTYPE = PTYPE_BIND; @@ -826,7 +814,7 @@ boolean rpch_in_send_bind(rdpRpch* rpch) bind_pdu->packed_drep[1] = 0x00; bind_pdu->packed_drep[2] = 0x00; bind_pdu->packed_drep[3] = 0x00; - bind_pdu->frag_length = 124 + (ntlm_stream->p - ntlm_stream->data); + bind_pdu->frag_length = 124 + ntlm_stream->size; bind_pdu->auth_length = ntlm_stream->size; bind_pdu->call_id = 2; bind_pdu->max_xmit_frag = 0x0FF8; @@ -918,7 +906,7 @@ boolean rpch_in_send_bind(rdpRpch* rpch) stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); /* TODO there is some allocated memory */ xfree(bind_pdu); @@ -928,13 +916,14 @@ boolean rpch_in_send_bind(rdpRpch* rpch) boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) { + rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); ntlm_authenticate(rpch->ntlm); ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; - rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu = xmalloc(sizeof(rpcconn_rpc_auth_3_hdr_t)); + rpc_auth_3_pdu = xnew(rpcconn_rpc_auth_3_hdr_t); rpc_auth_3_pdu->rpc_vers = 5; rpc_auth_3_pdu->rpc_vers_minor = 0; rpc_auth_3_pdu->PTYPE = PTYPE_RPC_AUTH_3; @@ -943,7 +932,7 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) rpc_auth_3_pdu->packed_drep[1] = 0x00; rpc_auth_3_pdu->packed_drep[2] = 0x00; rpc_auth_3_pdu->packed_drep[3] = 0x00; - rpc_auth_3_pdu->frag_length = 28 + (ntlm_stream->p - ntlm_stream->data); + rpc_auth_3_pdu->frag_length = 28 + ntlm_stream->size; rpc_auth_3_pdu->auth_length = ntlm_stream->size; rpc_auth_3_pdu->call_id = 2; rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; @@ -969,7 +958,7 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8); stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); xfree(rpc_auth_3_pdu); @@ -978,8 +967,9 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) boolean rpch_in_send_flow_control(rdpRpch* rpch) { - STREAM* pdu = stream_new(56); + STREAM* s = stream_new(56); + uint8* b; uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; uint8 ptype = PTYPE_RTS; @@ -990,46 +980,42 @@ boolean rpch_in_send_flow_control(rdpRpch* rpch) uint32 call_id = 0x00000000; uint16 flags = 0x0002; uint16 num_commands = 0x0002; - - /* ClientKeepalive */ uint32 ckCommandType = 0x0000000d; uint32 ClientKeepalive = 0x00000003; - - /* */ uint32 a = 0x00000001; uint32 aa = rpch->BytesReceived; uint32 aaa = 0x00010000; + rpch->AwailableWindow = aaa; + b = rpch->OUTChannelCookie; - uint8* b = rpch->OUTChannelCookie; + 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_write_uint32(s, a); + stream_write_uint32(s, aa); + stream_write_uint32(s, aaa); + stream_write(s, b, 16); - stream_write_uint8(pdu, rpc_vers); - stream_write_uint8(pdu, rpc_vers_minor); - stream_write_uint8(pdu, ptype); - stream_write_uint8(pdu, pfc_flags); - stream_write_uint32(pdu, packet_drep); - stream_write_uint16(pdu, frag_length); - stream_write_uint16(pdu, auth_length); - stream_write_uint32(pdu, call_id); - stream_write_uint16(pdu, flags); - stream_write_uint16(pdu, num_commands); - stream_write_uint32(pdu, ckCommandType); - stream_write_uint32(pdu, ClientKeepalive); - stream_write_uint32(pdu, a); - stream_write_uint32(pdu, aa); - stream_write_uint32(pdu, aaa); - stream_write(pdu, b, 16); + rpch_in_write(rpch, s->data, stream_get_length(s)); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); - - stream_free(pdu); + stream_free(s); return true; } boolean rpch_in_send_ping(rdpRpch* rpch) { - STREAM* pdu = stream_new(20); + STREAM* s = stream_new(20); uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; @@ -1042,20 +1028,20 @@ boolean rpch_in_send_ping(rdpRpch* rpch) uint16 flags = 0x0001; uint16 num_commands = 0x0000; - stream_write_uint8(pdu, rpc_vers); - stream_write_uint8(pdu, rpc_vers_minor); - stream_write_uint8(pdu, ptype); - stream_write_uint8(pdu, pfc_flags); - stream_write_uint32(pdu, packet_drep); - stream_write_uint16(pdu, frag_length); - stream_write_uint16(pdu, auth_length); - stream_write_uint32(pdu, call_id); - stream_write_uint16(pdu, flags); - stream_write_uint16(pdu, num_commands); + 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); - rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + rpch_in_write(rpch, s->data, stream_get_length(s)); - stream_free(pdu); + stream_free(s); return true; } @@ -1063,9 +1049,9 @@ boolean rpch_in_send_ping(rdpRpch* rpch) int rpch_out_read_http_header(rdpRpch* rpch) { int status; + STREAM* http_stream; rdpTls* tls_out = rpch->tls_out; rdpRpchHTTP* http_out = rpch->http_out; - STREAM* http_stream; http_stream = stream_new(1024); /* hope the header will not be larger */ http_out->contentLength = 0; @@ -1085,7 +1071,7 @@ int rpch_out_read_http_header(rdpRpch* rpch) { int i = 0; - while (*(stream_get_tail(http_stream)-1) != '\n') + while (*(stream_get_tail(http_stream) - 1) != '\n') { status = tls_read(tls_out, stream_get_tail(http_stream), 1); @@ -1095,7 +1081,7 @@ int rpch_out_read_http_header(rdpRpch* rpch) stream_seek(http_stream, 1); i++; - if (*(stream_get_tail(http_stream)-1) == ' ') + if (*(stream_get_tail(http_stream) - 1) == ' ') i--; } @@ -1217,8 +1203,10 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) rpch_in_send_flow_control(rpch); /* Send FlowControlAck every time AW reaches the half */ if (http_out->remContentLength <= 0xFFFF) /* TODO make ChannelRecycling */ + { if (rpch_out_read_http_header(rpch) < 0) return -1; + } pdu = xmalloc(0xFFFF); @@ -1277,16 +1265,21 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) int rpch_out_recv_bind_ack(rdpRpch* rpch) { + uint16 frag_length; + uint16 auth_length; + STREAM* ntlmssp_stream; int pdu_length = 0x8FFF; /* 32KB buffer */ uint8* pdu = xmalloc(pdu_length); int status = rpch_out_read(rpch, pdu, pdu_length); + DEBUG_RPCH("TODO: complete NTLM integration"); + if (status > 0) { - uint16 frag_length = *((uint16*)(pdu + 8)); - uint16 auth_length = *((uint16*)(pdu + 10)); + frag_length = *((uint16*)(pdu + 8)); + auth_length = *((uint16*)(pdu + 10)); - STREAM* ntlmssp_stream = stream_new(0xFFFF); + ntlmssp_stream = stream_new(0xFFFF); stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); ntlmssp_stream->p = ntlmssp_stream->data; @@ -1303,13 +1296,14 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) { int i; int status = -1; + rpcconn_request_hdr_t* request_pdu; uint8 auth_pad_length = 16 - ((24 + length + 8 + 16) % 16); if (auth_pad_length == 16) auth_pad_length = 0; - rpcconn_request_hdr_t* request_pdu = xmalloc(sizeof(rpcconn_request_hdr_t)); + request_pdu = xnew(rpcconn_request_hdr_t); request_pdu->rpc_vers = 5; request_pdu->rpc_vers_minor = 0; request_pdu->PTYPE = PTYPE_REQUEST; @@ -1325,7 +1319,7 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) /* opnum=8 means [MS-TSGU] TsProxySetupRecievePipe, save call_id for checking pipe responses */ if (opnum == 8) - rpch->pipe_call_id=rpch->call_id; + rpch->pipe_call_id = rpch->call_id; request_pdu->alloc_hint = length; request_pdu->p_cont_id = 0x0000; @@ -1337,7 +1331,9 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) request_pdu->auth_verifier.auth_pad = xmalloc(auth_pad_length); /* align(4); size_is(auth_pad_length) p */ for (i = 0; i < auth_pad_length; i++) + { request_pdu->auth_verifier.auth_pad[i] = 0x00; + } request_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ request_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ @@ -1355,7 +1351,10 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) rdpBlob rdpMsg; rdpMsg.data = pdu->data; - rdpMsg.length = pdu->p - pdu->data; + rdpMsg.length = stream_get_length(pdu); + + DEBUG_RPCH("TODO: complete NTLM integration"); + //ntlmssp_encrypt_message(rpch->ntlmssp, &rdpMsg, NULL, request_pdu->auth_verifier.auth_value); stream_write(pdu, request_pdu->auth_verifier.auth_value, request_pdu->auth_length); @@ -1377,15 +1376,15 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) int rpch_read(rdpRpch* rpch, uint8* data, int length) { - int rpch_length = length + 0xFF; int status; - int readed = 0; + int read = 0; int data_length; - uint8* rpch_data = xmalloc(rpch_length); uint16 frag_length; uint16 auth_length; uint8 auth_pad_length; uint32 call_id = -1; + int rpch_length = length + 0xFF; + uint8* rpch_data = xmalloc(rpch_length); if (rpch->read_buffer_len > 0) { @@ -1397,7 +1396,7 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) } memcpy(data, rpch->read_buffer, rpch->read_buffer_len); - readed += rpch->read_buffer_len; + read += rpch->read_buffer_len; xfree(rpch->read_buffer); rpch->read_buffer_len = 0; } @@ -1409,7 +1408,7 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) if (status == 0) { xfree(rpch_data); - return readed; + return read; } else if (status < 0) { @@ -1432,9 +1431,9 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) if (status == 4) continue; - if (readed + data_length > length) /* if read data is greater then given buffer */ + if (read + data_length > length) /* if read data is greater then given buffer */ { - rpch->read_buffer_len = readed + data_length - length; + rpch->read_buffer_len = read + data_length - length; rpch->read_buffer = xmalloc(rpch->read_buffer_len); data_length -= rpch->read_buffer_len; @@ -1442,18 +1441,19 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) memcpy(rpch->read_buffer, rpch_data + 24 + data_length, rpch->read_buffer_len); } - memcpy(data + readed, rpch_data + 24, data_length); + memcpy(data + read, rpch_data + 24, data_length); - readed += data_length; + read += data_length; - if (status > data_length && readed < length) + if (status > data_length && read < length) continue; break; } xfree(rpch_data); - return readed; + + return read; } boolean rpch_connect(rdpRpch* rpch) diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 5eff258bd..ecf3478d0 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -95,6 +95,8 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } + DEBUG_TSG("rpch_connect success"); + status = rpch_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) From fb0d09080dc5bf892447d4632a25018fefa5be4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 28 Mar 2012 15:07:57 -0400 Subject: [PATCH 07/47] libfreerdp-core: start separating HTTP encoding methods (TSG) --- include/freerdp/sspi/sspi.h | 3 + libfreerdp-core/rpch.c | 179 +++++++++++++++++------------------- libfreerdp-crypto/crypto.c | 2 +- libfreerdp-sspi/sspi.h | 3 - 4 files changed, 86 insertions(+), 101 deletions(-) diff --git a/include/freerdp/sspi/sspi.h b/include/freerdp/sspi/sspi.h index 9bfde2f60..70df34074 100644 --- a/include/freerdp/sspi/sspi.h +++ b/include/freerdp/sspi/sspi.h @@ -956,4 +956,7 @@ FREERDP_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSe void sspi_GlobalInit(); void sspi_GlobalFinish(); +void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size); +void sspi_SecBufferFree(PSecBuffer SecBuffer); + #endif /* FREERDP_SSPI_H */ diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index 23e1570d7..8ca915072 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -118,12 +118,6 @@ boolean ntlm_authenticate(rdpNtlm* ntlm) 0, &ntlm->context, &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration); - if (ntlm->inputBuffer.pvBuffer != NULL) - { - xfree(ntlm->inputBuffer.pvBuffer); - ntlm->inputBuffer.pvBuffer = NULL; - } - if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) { if (ntlm->table->CompleteAuthToken != NULL) @@ -173,63 +167,85 @@ void ntlm_free(rdpNtlm* ntlm) } } +STREAM* rpch_ntlm_http_out_data(rdpRpch* rpch, SecBuffer* ntlm_token, uint8* content, int length) +{ + STREAM* s; + char* int_str; + int total_length; + int int_str_length; + rdpSettings* settings; + int tsg_hostname_length; + int ntlm_token_base64_length; + uint8* ntlm_token_base64_data; + + settings = rpch->settings; + int_str_length = snprintf(NULL, 0, "%d", length); + tsg_hostname_length = strlen(settings->tsg_hostname); + + int_str = xmalloc(int_str_length + 1); + snprintf(int_str, int_str_length + 1, "%d", length); + + crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer, &ntlm_token_base64_data, &ntlm_token_base64_length); + + total_length = 55 + 24 + 24 + 23 + 16 + int_str_length + 1 + 18 + 6 + + tsg_hostname_length + 1 + 110 + 20 + ntlm_token_base64_length + 2; + + s = stream_new(total_length); + + stream_write(s, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); + stream_write(s, "Accept: application/rpc\n", 24); + stream_write(s, "Cache-Control: no-cache\n", 24); + stream_write(s, "Connection: Keep-Alive\n", 23); + + stream_write(s, "Content-Length: ", 16); + stream_write(s, int_str, int_str_length); + stream_write(s, "\n", 1); + + stream_write(s, "User-Agent: MSRPC\n", 18); + stream_write(s, "Host: ", 6); + stream_write(s, settings->tsg_hostname, tsg_hostname_length); + stream_write(s, "\n", 1); + stream_write(s, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); + stream_write(s, "Authorization: NTLM ", 20); + stream_write(s, ntlm_token_base64_data, ntlm_token_base64_length); + stream_write(s, "\n\n", 2); + stream_seal(s); + + return s; +} + boolean rpch_out_connect_http(rdpRpch* rpch) { STREAM* http_stream; STREAM* ntlm_stream; - int decoded_ntht_length; - int encoded_ntht_length; - uint8* decoded_ntht_data = NULL; - uint8* encoded_ntht_data = NULL; + int decoded_ntlm_http_length; + int encoded_ntlm_http_length; + uint8* decoded_ntlm_http_data = NULL; + uint8* encoded_ntlm_http_data = NULL; rdpTls* tls_out = rpch->tls_out; rdpSettings* settings = rpch->settings; rdpRpchHTTP* http_out = rpch->http_out; rdpNtlm* http_out_ntlm = http_out->ntlm; - http_stream = stream_new(0xFFFF); - ntlm_stream = stream_new(0xFFFF); + ntlm_stream = stream_new(0); printf("rpch_out_connect_http\n"); ntlm_client_init(http_out_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_out_ntlm); - ntlm_stream->size = http_out_ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = http_out_ntlm->outputBuffer.pvBuffer; - decoded_ntht_length = ntlm_stream->size; - decoded_ntht_data = xmalloc(decoded_ntht_length); - stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - - stream_clear(ntlm_stream); - ntlm_stream->p = ntlm_stream->data; - - crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); - - stream_write(http_stream, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); - stream_write(http_stream, "Accept: application/rpc\n", 24); - stream_write(http_stream, "Cache-Control: no-cache\n", 24); - stream_write(http_stream, "Connection: Keep-Alive\n", 23); - stream_write(http_stream, "Content-Length: 0\n", 18); - stream_write(http_stream, "User-Agent: MSRPC\n", 18); - stream_write(http_stream, "Host: ", 6); - stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); - stream_write(http_stream, "\n", 1); - stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); - stream_write(http_stream, "Authorization: NTLM ", 20); - stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); - stream_write(http_stream, "\n\n", 2); + http_stream = rpch_ntlm_http_out_data(rpch, &http_out_ntlm->outputBuffer, NULL, 0); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); - tls_write(tls_out, http_stream->data, http_stream->p - http_stream->data); + tls_write(tls_out, http_stream->data, http_stream->size); + http_stream = stream_new(0xFFFF); stream_clear(http_stream); http_stream->p = http_stream->data; - xfree(decoded_ntht_data); - - encoded_ntht_length = -1; - xfree(encoded_ntht_data); - encoded_ntht_data = NULL; + encoded_ntlm_http_length = -1; + xfree(encoded_ntlm_http_data); + encoded_ntlm_http_data = NULL; uint8 buffer_byte; http_out->contentLength = 0; @@ -239,28 +255,28 @@ boolean rpch_out_connect_http(rdpRpch* rpch) tls_read(tls_out, &buffer_byte, 1); stream_write(http_stream, &buffer_byte, 1); - if (encoded_ntht_length == -1) + if (encoded_ntlm_http_length == -1) { - uint8* start_of_ntht_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); + uint8* start_of_ntlm_http_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); - if (start_of_ntht_data != NULL) + if (start_of_ntlm_http_data != NULL) { - start_of_ntht_data += 5; + start_of_ntlm_http_data += 5; - for (encoded_ntht_length = 0; ; encoded_ntht_length++) + for (encoded_ntlm_http_length = 0; ; encoded_ntlm_http_length++) { tls_read(tls_out, &buffer_byte, 1); stream_write(http_stream, &buffer_byte, 1); - if (start_of_ntht_data[encoded_ntht_length] == '\n') + if (start_of_ntlm_http_data[encoded_ntlm_http_length] == '\n') { - encoded_ntht_length--; /* \r */ + encoded_ntlm_http_length--; /* \r */ break; } } - encoded_ntht_data = xmalloc(encoded_ntht_length); - memcpy(encoded_ntht_data, start_of_ntht_data, encoded_ntht_length); + encoded_ntlm_http_data = xmalloc(encoded_ntlm_http_length); + memcpy(encoded_ntlm_http_data, start_of_ntlm_http_data, encoded_ntlm_http_length); } } @@ -300,60 +316,27 @@ boolean rpch_out_connect_http(rdpRpch* rpch) stream_clear(http_stream); http_stream->p = http_stream->data; - if (encoded_ntht_length == 0) /* No NTLM data was found */ + if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; - crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); + crypto_base64_decode(encoded_ntlm_http_data, encoded_ntlm_http_length, &decoded_ntlm_http_data, &decoded_ntlm_http_length); - stream_write(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - ntlm_stream->p = ntlm_stream->data; - - xfree(decoded_ntht_data); - xfree(encoded_ntht_data); - - http_out_ntlm->inputBuffer.pvBuffer = ntlm_stream->data; - http_out_ntlm->inputBuffer.cbBuffer = ntlm_stream->size; + http_out_ntlm->inputBuffer.pvBuffer = decoded_ntlm_http_data; + http_out_ntlm->inputBuffer.cbBuffer = decoded_ntlm_http_length; ntlm_authenticate(http_out_ntlm); - stream_clear(ntlm_stream); - ntlm_stream->size = http_out_ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = http_out_ntlm->outputBuffer.pvBuffer; - - decoded_ntht_length = ntlm_stream->size; - decoded_ntht_data = xmalloc(decoded_ntht_length); - stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - - stream_clear(ntlm_stream); - ntlm_stream->p = ntlm_stream->data; - - crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); - - stream_write(http_stream, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); - stream_write(http_stream, "Accept: application/rpc\n", 24); - stream_write(http_stream, "Cache-Control: no-cache\n", 24); - stream_write(http_stream, "Connection: Keep-Alive\n", 23); - stream_write(http_stream, "Content-Length: 76\n", 19); - stream_write(http_stream, "User-Agent: MSRPC\n", 18); - stream_write(http_stream, "Host: ", 6); - stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); - stream_write(http_stream, "\n", 1); - stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); - stream_write(http_stream, "Authorization: NTLM ", 20); - stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); - stream_write(http_stream, "\n\n", 2); http_out->contentLength = 76; http_out->remContentLength = 76; + http_stream = rpch_ntlm_http_out_data(rpch, &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); - - tls_write(tls_out, http_stream->data, http_stream->p - http_stream->data); - + tls_write(tls_out, http_stream->data, http_stream->size); stream_clear(http_stream); - http_stream->p = http_stream->data; - xfree(decoded_ntht_data); - xfree(encoded_ntht_data); + xfree(decoded_ntlm_http_data); + xfree(encoded_ntlm_http_data); /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ http_out->state = RPCH_HTTP_SENDING; @@ -377,6 +360,8 @@ boolean rpch_in_connect_http(rdpRpch* rpch) ntlm_stream = stream_new(0xFFFF); http_stream = stream_new(0xFFFF); + printf("rpch_in_connect_http\n"); + ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_in_ntlm); @@ -1245,7 +1230,7 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) if (length < frag_length) { - printf("rcph_out_read(): Error! Given buffer is to small. Recieved data fits not in.\n"); + printf("rcph_out_read(): Error! Given buffer is to small. Received data fits not in.\n"); xfree(pdu); return -1; /* TODO add buffer for storing remaining data for the next read in case destination buffer is too small */ } @@ -1253,9 +1238,9 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) memcpy(data, pdu, frag_length); #ifdef WITH_DEBUG_RPCH - printf("\nrpch_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); - freerdp_hexdump(data, frag_length); - printf("\n"); + //printf("\nrpch_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); + //freerdp_hexdump(data, frag_length); + //printf("\n"); #endif xfree(pdu); diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp-crypto/crypto.c index b01ebb2b3..d84e0e68c 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp-crypto/crypto.c @@ -524,7 +524,7 @@ void crypto_base64_encode(uint8* data, int length, uint8** enc_data, int* res_le BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); - *res_length = bptr->length-1; + *res_length = bptr->length - 1; *enc_data = xmalloc(*res_length); memcpy(*enc_data, bptr->data, *res_length); diff --git a/libfreerdp-sspi/sspi.h b/libfreerdp-sspi/sspi.h index 0cac339c4..e8c01a638 100644 --- a/libfreerdp-sspi/sspi.h +++ b/libfreerdp-sspi/sspi.h @@ -33,9 +33,6 @@ typedef struct _CREDENTIALS CREDENTIALS; CREDENTIALS* sspi_CredentialsNew(); void sspi_CredentialsFree(CREDENTIALS* credentials); -void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size); -void sspi_SecBufferFree(PSecBuffer SecBuffer); - SecHandle* sspi_SecureHandleAlloc(); void sspi_SecureHandleInit(SecHandle* handle); void sspi_SecureHandleInvalidate(SecHandle* handle); From e9aee05684d16210b14b01112bc396ac3a07e0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 28 Mar 2012 15:26:33 -0400 Subject: [PATCH 08/47] libfreerdp-core: cleanup rpch_in_send() HTTP encoding --- libfreerdp-core/rpch.c | 175 +++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 112 deletions(-) diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpch.c index 8ca915072..3a4eb88fc 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpch.c @@ -167,18 +167,22 @@ void ntlm_free(rdpNtlm* ntlm) } } -STREAM* rpch_ntlm_http_out_data(rdpRpch* rpch, SecBuffer* ntlm_token, uint8* content, int length) +STREAM* rpch_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, uint8* content, int length) { STREAM* s; char* int_str; int total_length; int int_str_length; + int command_length; rdpSettings* settings; int tsg_hostname_length; int ntlm_token_base64_length; uint8* ntlm_token_base64_data; settings = rpch->settings; + + command_length = strlen(command); + int_str_length = snprintf(NULL, 0, "%d", length); tsg_hostname_length = strlen(settings->tsg_hostname); @@ -192,7 +196,8 @@ STREAM* rpch_ntlm_http_out_data(rdpRpch* rpch, SecBuffer* ntlm_token, uint8* con s = stream_new(total_length); - stream_write(s, "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 55); + stream_write(s, command, command_length); + stream_write(s, " /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 43); stream_write(s, "Accept: application/rpc\n", 24); stream_write(s, "Cache-Control: no-cache\n", 24); stream_write(s, "Connection: Keep-Alive\n", 23); @@ -235,7 +240,7 @@ boolean rpch_out_connect_http(rdpRpch* rpch) ntlm_authenticate(http_out_ntlm); - http_stream = rpch_ntlm_http_out_data(rpch, &http_out_ntlm->outputBuffer, NULL, 0); + http_stream = rpch_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); @@ -329,7 +334,7 @@ boolean rpch_out_connect_http(rdpRpch* rpch) http_out->contentLength = 76; http_out->remContentLength = 76; - http_stream = rpch_ntlm_http_out_data(rpch, &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); + http_stream = rpch_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); @@ -348,61 +353,36 @@ boolean rpch_in_connect_http(rdpRpch* rpch) { STREAM* ntlm_stream; STREAM* http_stream; - int decoded_ntht_length; - int encoded_ntht_length; - uint8* decoded_ntht_data = NULL; - uint8* encoded_ntht_data = NULL; + int decoded_ntlm_http_length; + int encoded_ntlm_http_length; + uint8* decoded_ntlm_http_data = NULL; + uint8* encoded_ntlm_http_data = NULL; rdpTls* tls_in = rpch->tls_in; rdpSettings* settings = rpch->settings; rdpRpchHTTP* http_in = rpch->http_in; rdpNtlm* http_in_ntlm = http_in->ntlm; - ntlm_stream = stream_new(0xFFFF); - http_stream = stream_new(0xFFFF); + ntlm_stream = stream_new(0); printf("rpch_in_connect_http\n"); ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_in_ntlm); - ntlm_stream->size = http_in_ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = http_in_ntlm->outputBuffer.pvBuffer; - decoded_ntht_length = ntlm_stream->p - ntlm_stream->data; - decoded_ntht_data = xmalloc(decoded_ntht_length); - - ntlm_stream->p = ntlm_stream->data; - stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - - stream_clear(ntlm_stream); - ntlm_stream->p = ntlm_stream->data; - - crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); - - stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); - stream_write(http_stream, "Accept: application/rpc\n", 24); - stream_write(http_stream, "Cache-Control: no-cache\n", 24); - stream_write(http_stream, "Connection: Keep-Alive\n", 23); - stream_write(http_stream, "Content-Length: 0\n", 18); - stream_write(http_stream, "User-Agent: MSRPC\n", 18); - stream_write(http_stream, "Host: ", 6); - stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); - stream_write(http_stream, "\n", 1); - stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); - stream_write(http_stream, "Authorization: NTLM ", 20); - stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); - stream_write(http_stream, "\n\n", 2); + http_stream = rpch_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); - tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data); + tls_write(tls_in, http_stream->data, http_stream->size); + http_stream = stream_new(0xFFFF); stream_clear(http_stream); http_stream->p = http_stream->data; - xfree(decoded_ntht_data); + xfree(decoded_ntlm_http_data); - encoded_ntht_length = -1; - xfree(encoded_ntht_data); - encoded_ntht_data = NULL; + encoded_ntlm_http_length = -1; + xfree(encoded_ntlm_http_data); + encoded_ntlm_http_data = NULL; uint8 buffer_byte; http_in->contentLength = 0; @@ -412,7 +392,7 @@ boolean rpch_in_connect_http(rdpRpch* rpch) tls_read(tls_in, &buffer_byte, 1); stream_write(http_stream, &buffer_byte, 1); - if (encoded_ntht_length == -1) + if (encoded_ntlm_http_length == -1) { uint8* start_of_ntht_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); @@ -420,20 +400,20 @@ boolean rpch_in_connect_http(rdpRpch* rpch) { start_of_ntht_data += 5; - for (encoded_ntht_length=0;;encoded_ntht_length++) + for (encoded_ntlm_http_length=0;;encoded_ntlm_http_length++) { tls_read(tls_in, &buffer_byte, 1); stream_write(http_stream, &buffer_byte, 1); - if (start_of_ntht_data[encoded_ntht_length]=='\n') + if (start_of_ntht_data[encoded_ntlm_http_length]=='\n') { - encoded_ntht_length--; /* \r */ + encoded_ntlm_http_length--; /* \r */ break; } } - encoded_ntht_data = xmalloc(encoded_ntht_length); - memcpy(encoded_ntht_data, start_of_ntht_data, encoded_ntht_length); + encoded_ntlm_http_data = xmalloc(encoded_ntlm_http_length); + memcpy(encoded_ntlm_http_data, start_of_ntht_data, encoded_ntlm_http_length); } } @@ -473,60 +453,30 @@ boolean rpch_in_connect_http(rdpRpch* rpch) stream_clear(http_stream); http_stream->p = http_stream->data; - if (encoded_ntht_length == 0) /* No NTLM data was found */ + if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; - crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); + crypto_base64_decode(encoded_ntlm_http_data, encoded_ntlm_http_length, &decoded_ntlm_http_data, &decoded_ntlm_http_length); - stream_write(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - ntlm_stream->p = ntlm_stream->data; - - xfree(decoded_ntht_data); - xfree(encoded_ntht_data); - - http_in_ntlm->inputBuffer.pvBuffer = ntlm_stream->data; - http_in_ntlm->inputBuffer.cbBuffer = ntlm_stream->size; + http_in_ntlm->inputBuffer.pvBuffer = decoded_ntlm_http_data; + http_in_ntlm->inputBuffer.cbBuffer = decoded_ntlm_http_length; ntlm_authenticate(http_in_ntlm); - stream_clear(ntlm_stream); - ntlm_stream->size = http_in_ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = http_in_ntlm->outputBuffer.pvBuffer; - - decoded_ntht_length = ntlm_stream->size; - decoded_ntht_data = xmalloc(decoded_ntht_length); - stream_read(ntlm_stream, decoded_ntht_data, decoded_ntht_length); - - stream_clear(ntlm_stream); - ntlm_stream->p = ntlm_stream->data; - - crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); - - stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); - stream_write(http_stream, "Accept: application/rpc\n", 24); - stream_write(http_stream, "Cache-Control: no-cache\n", 24); - stream_write(http_stream, "Connection: Keep-Alive\n", 23); - stream_write(http_stream, "Content-Length: 1073741824\n", 27); - stream_write(http_stream, "User-Agent: MSRPC\n", 18); - stream_write(http_stream, "Host: ", 6); - stream_write(http_stream, settings->tsg_hostname, strlen(settings->tsg_hostname)); - stream_write(http_stream, "\n", 1); - stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); - stream_write(http_stream, "Authorization: NTLM ", 20); - stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); - stream_write(http_stream, "\n\n", 2); http_in->contentLength = 1073741824; http_in->remContentLength = 1073741824; + http_stream = rpch_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); + DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); - tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data); + tls_write(tls_in, http_stream->data, http_stream->size); stream_clear(http_stream); http_stream->p = http_stream->data; - xfree(decoded_ntht_data); - xfree(encoded_ntht_data); + xfree(decoded_ntlm_http_data); + xfree(encoded_ntlm_http_data); /* At this point IN connection is ready to send CONN/B1 and start with sending data */ http_in->state = RPCH_HTTP_SENDING; @@ -677,7 +627,7 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) boolean rpch_in_send_CONN_B1(rdpRpch* rpch) { - STREAM* pdu = stream_new(104); + STREAM* s = stream_new(104); DEBUG_RPCH("Sending CONN_B1"); @@ -702,35 +652,36 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) uint32 agidCommandType = 0x0000000c; uint8* AssociationGroupId; - rpch->INChannelCookie = rpch_create_cookie(); /* 16bytes */ + rpch->INChannelCookie = rpch_create_cookie(); /* 16 bytes */ AssociationGroupId = rpch_create_cookie(); /* 16 bytes */ - stream_write_uint8(pdu, rpc_vers); - stream_write_uint8(pdu, rpc_vers_minor); - stream_write_uint8(pdu, ptype); - stream_write_uint8(pdu, pfc_flags); - stream_write_uint32(pdu, packet_drep); - stream_write_uint16(pdu, frag_length); - stream_write_uint16(pdu, auth_length); - stream_write_uint32(pdu, call_id); - stream_write_uint16(pdu, flags); - stream_write_uint16(pdu, num_commands); - stream_write_uint32(pdu, vCommandType); - stream_write_uint32(pdu, Version); - stream_write_uint32(pdu, vccCommandType); - stream_write(pdu, rpch->virtualConnectionCookie, 16); - stream_write_uint32(pdu, iccCommandType); - stream_write(pdu, rpch->INChannelCookie, 16); - stream_write_uint32(pdu, clCommandType); - stream_write_uint32(pdu, ChannelLifetime); - stream_write_uint32(pdu, ckCommandType); - stream_write_uint32(pdu, ClientKeepalive); - stream_write_uint32(pdu, agidCommandType); - stream_write(pdu, AssociationGroupId, 16); + 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, vCommandType); + stream_write_uint32(s, Version); + stream_write_uint32(s, vccCommandType); + stream_write(s, rpch->virtualConnectionCookie, 16); + stream_write_uint32(s, iccCommandType); + stream_write(s, rpch->INChannelCookie, 16); + stream_write_uint32(s, clCommandType); + stream_write_uint32(s, ChannelLifetime); + stream_write_uint32(s, ckCommandType); + stream_write_uint32(s, ClientKeepalive); + stream_write_uint32(s, agidCommandType); + stream_write(s, AssociationGroupId, 16); + stream_seal(s); - rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); + rpch_in_write(rpch, s->data, s->size); - stream_free(pdu); + stream_free(s); return true; } From b6af8cd206ef46407a0de447a88924baf77da374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 31 Mar 2012 21:32:13 -0400 Subject: [PATCH 09/47] libfreerdp-core: added MS-TSGU interface definitions --- include/freerdp/wintypes.h | 12 ++ libfreerdp-core/tsg.c | 107 ++++++++++++++++++ libfreerdp-core/tsg.h | 218 +++++++++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) diff --git a/include/freerdp/wintypes.h b/include/freerdp/wintypes.h index b6b5d2e33..df652c86e 100644 --- a/include/freerdp/wintypes.h +++ b/include/freerdp/wintypes.h @@ -41,6 +41,7 @@ typedef int BOOL, *PBOOL, *LPBOOL; typedef unsigned char BYTE, *PBYTE, *LPBYTE; +typedef BYTE byte; typedef BYTE BOOLEAN, *PBOOLEAN; typedef wchar_t WCHAR, *PWCHAR; typedef WCHAR* BSTR; @@ -100,6 +101,17 @@ typedef unsigned short USHORT; typedef void VOID, *PVOID, *LPVOID; typedef unsigned short WORD, *PWORD, *LPWORD; +typedef void* PCONTEXT_HANDLE; +typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; + +typedef struct _GUID +{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + byte Data4[8]; +} GUID, UUID, *PGUID; + #ifdef UNICODE #define _T(x) L ## x #else diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index ecf3478d0..71f41094b 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -73,6 +73,60 @@ uint8 tsg_packet5[20] = 0x00, 0x00, 0x00, 0x00 }; +void Opnum0NotUsedOnWire(void) +{ + return; +} + +HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, + PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId) +{ + return 0; +} + +HRESULT TsProxyAuthorizeTunnel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse) +{ + return 0; +} + +HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + unsigned long procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse) +{ + return 0; +} + +HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId) +{ + return 0; +} + +void Opnum5NotUsedOnWire(void) +{ + return; +} + +HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context) +{ + return 0; +} + +HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context) +{ + return 0; +} + +DWORD TsProxySetupReceivePipe(byte pRpcMessage[]) +{ + return 0; +} + +DWORD TsProxySendToServer(byte pRpcMessage[]) +{ + return 0; +} + boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { int status = -1; @@ -97,6 +151,17 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) DEBUG_TSG("rpch_connect success"); + /** + * OpNum = 1 + * + * HRESULT TsProxyCreateTunnel( + * [in, ref] PTSG_PACKET tsgPacket, + * [out, ref] PTSG_PACKET* tsgPacketResponse, + * [out] PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, + * [out] unsigned long* tunnelId + * ); + */ + status = rpch_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) @@ -126,6 +191,17 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) memcpy(tsg_packet2 + 4, tsg->tunnelContext, 16); + /** + * OpNum = 2 + * + * HRESULT TsProxyAuthorizeTunnel( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in, ref] PTSG_PACKET tsgPacket, + * [out, ref] PTSG_PACKET* tsgPacketResponse + * ); + * + */ + status = rpch_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) @@ -145,6 +221,17 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) memcpy(tsg_packet3 + 4, tsg->tunnelContext, 16); status = rpch_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); + /** + * OpNum = 3 + * + * HRESULT TsProxyMakeTunnelCall( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in] unsigned long procId, + * [in, ref] PTSG_PACKET tsgPacket, + * [out, ref] PTSG_PACKET* tsgPacketResponse + * ); + */ + if (status <= 0) { printf("rpch_write opnum=3 failed!\n"); @@ -168,6 +255,17 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) stream_write(s_p4, dest_addr_unic, dest_addr_unic_len); stream_write_uint16(s_p4,0x0000); /* unicode zero to terminate hostname string */ + /** + * OpNum = 4 + * + * HRESULT TsProxyCreateChannel( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in, ref] PTSENDPOINTINFO tsEndPointInfo, + * [out] PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, + * [out] unsigned long* channelId + * ); + */ + status = rpch_write(rpch, s_p4->data, s_p4->size, 4); if (status <= 0) @@ -195,6 +293,15 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) #endif memcpy(tsg_packet5 + 4, tsg->channelContext, 16); + + /** + * OpNum = 8 + * + * DWORD TsProxySetupReceivePipe( + * [in, max_is(32767)] byte pRpcMessage[] + * ); + */ + status = rpch_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index f8522af7d..690676d0c 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -28,6 +28,7 @@ typedef struct rdp_tsg rdpTsg; #include #include +#include #include #include #include @@ -42,6 +43,223 @@ struct rdp_tsg rdpTransport* transport; }; +typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE; +typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE; + +typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE; +typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE; + +typedef wchar_t* RESOURCENAME; + +#define MAX_RESOURCE_NAMES 50 + +typedef struct _tsendpointinfo +{ + RESOURCENAME* resourceName; + unsigned long numResourceNames; + RESOURCENAME* alternateResourceNames; + unsigned short numAlternateResourceNames; + unsigned long Port; +} TSENDPOINTINFO, *PTSENDPOINTINFO; + +#define TSG_PACKET_TYPE_HEADER 0x00004844 +#define TSG_PACKET_TYPE_VERSIONCAPS 0x00005643 +#define TSG_PACKET_TYPE_QUARCONFIGREQUEST 0x00005143 +#define TSG_PACKET_TYPE_QUARREQUEST 0x00005152 +#define TSG_PACKET_TYPE_RESPONSE 0x00005052 +#define TSG_PACKET_TYPE_QUARENC_RESPONSE 0x00004552 +#define TSG_CAPABILITY_TYPE_NAP 0x00000001 +#define TSG_PACKET_TYPE_CAPS_RESPONSE 0x00004350 +#define TSG_PACKET_TYPE_MSGREQUEST_PACKET 0x00004752 +#define TSG_PACKET_TYPE_MESSAGE_PACKET 0x00004750 +#define TSG_PACKET_TYPE_AUTH 0x00004054 +#define TSG_PACKET_TYPE_REAUTH 0x00005250 +#define TSG_ASYNC_MESSAGE_CONSENT_MESSAGE 0x00000001 +#define TSG_ASYNC_MESSAGE_SERVICE_MESSAGE 0x00000002 +#define TSG_ASYNC_MESSAGE_REAUTH 0x00000003 +#define TSG_TUNNEL_CALL_ASYNC_MSG_REQUEST 0x00000001 +#define TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST 0x00000002 + +typedef struct _TSG_PACKET_HEADER +{ + unsigned short ComponentId; + unsigned short PacketId; +} TSG_PACKET_HEADER, *PTSG_PACKET_HEADER; + +typedef struct _TSG_CAPABILITY_NAP +{ + unsigned long capabilities; +} TSG_CAPABILITY_NAP, *PTSG_CAPABILITY_NAP; + +typedef union +{ + TSG_CAPABILITY_NAP tsgCapNap; +} TSG_CAPABILITIES_UNION, *PTSG_CAPABILITIES_UNION; + +typedef struct _TSG_PACKET_CAPABILITIES +{ + unsigned long capabilityType; + TSG_CAPABILITIES_UNION tsgPacket; +} TSG_PACKET_CAPABILITIES, *PTSG_PACKET_CAPABILITIES; + +typedef struct _TSG_PACKET_VERSIONCAPS +{ + TSG_PACKET_HEADER tsgHeader; + PTSG_PACKET_CAPABILITIES tsgCaps; + unsigned long numCapabilities; + unsigned short majorVersion; + unsigned short minorVersion; + unsigned short quarantineCapabilities; +} TSG_PACKET_VERSIONCAPS, *PTSG_PACKET_VERSIONCAPS; + +typedef struct _TSG_PACKET_QUARCONFIGREQUEST +{ + unsigned long flags; +} TSG_PACKET_QUARCONFIGREQUEST, *PTSG_PACKET_QUARCONFIGREQUEST; + +typedef struct _TSG_PACKET_QUARREQUEST +{ + unsigned long flags; + wchar_t* machineName; + unsigned long nameLength; + byte* data; + unsigned long dataLen; +} TSG_PACKET_QUARREQUEST, *PTSG_PACKET_QUARREQUEST; + +typedef struct _TSG_REDIRECTION_FLAGS +{ + BOOL enableAllRedirections; + BOOL disableAllRedirections; + BOOL driveRedirectionDisabled; + BOOL printerRedirectionDisabled; + BOOL portRedirectionDisabled; + BOOL reserved; + BOOL clipboardRedirectionDisabled; + BOOL pnpRedirectionDisabled; +} TSG_REDIRECTION_FLAGS, *PTSG_REDIRECTION_FLAGS; + +typedef struct _TSG_PACKET_RESPONSE +{ + unsigned long flags; + unsigned long reserved; + byte* responseData; + unsigned long responseDataLen; + TSG_REDIRECTION_FLAGS redirectionFlags; +} TSG_PACKET_RESPONSE, *PTSG_PACKET_RESPONSE; + +typedef struct _TSG_PACKET_QUARENC_RESPONSE +{ + unsigned long flags; + unsigned long certChainLen; + wchar_t* certChainData; + GUID nonce; + PTSG_PACKET_VERSIONCAPS versionCaps; +} TSG_PACKET_QUARENC_RESPONSE, *PTSG_PACKET_QUARENC_RESPONSE; + +typedef struct TSG_PACKET_STRING_MESSAGE +{ + long isDisplayMandatory; + long isConsentMandatory; + unsigned long msgBytes; + wchar_t* msgBuffer; +} TSG_PACKET_STRING_MESSAGE, *PTSG_PACKET_STRING_MESSAGE; + +typedef struct TSG_PACKET_REAUTH_MESSAGE +{ + unsigned __int64 tunnelContext; +} TSG_PACKET_REAUTH_MESSAGE, *PTSG_PACKET_REAUTH_MESSAGE; + +typedef union +{ + PTSG_PACKET_STRING_MESSAGE consentMessage; + PTSG_PACKET_STRING_MESSAGE serviceMessage; + PTSG_PACKET_REAUTH_MESSAGE reauthMessage; +} TSG_PACKET_TYPE_MESSAGE_UNION, *PTSG_PACKET_TYPE_MESSAGE_UNION; + +typedef struct _TSG_PACKET_MSG_RESPONSE +{ + unsigned long msgID; + unsigned long msgType; + long isMsgPresent; + TSG_PACKET_TYPE_MESSAGE_UNION messagePacket; +} TSG_PACKET_MSG_RESPONSE, *PTSG_PACKET_MSG_RESPONSE; + +typedef struct TSG_PACKET_CAPS_RESPONSE +{ + TSG_PACKET_QUARENC_RESPONSE pktQuarEncResponse; + TSG_PACKET_MSG_RESPONSE pktConsentMessage; +} TSG_PACKET_CAPS_RESPONSE, *PTSG_PACKET_CAPS_RESPONSE; + +typedef struct TSG_PACKET_MSG_REQUEST +{ + unsigned long maxMessagesPerBatch; +} TSG_PACKET_MSG_REQUEST, *PTSG_PACKET_MSG_REQUEST; + +typedef struct _TSG_PACKET_AUTH +{ + TSG_PACKET_VERSIONCAPS tsgVersionCaps; + unsigned long cookieLen; + byte* cookie; +} TSG_PACKET_AUTH, *PTSG_PACKET_AUTH; + +typedef union +{ + PTSG_PACKET_VERSIONCAPS packetVersionCaps; + PTSG_PACKET_AUTH packetAuth; +} TSG_INITIAL_PACKET_TYPE_UNION, *PTSG_INITIAL_PACKET_TYPE_UNION; + +typedef struct TSG_PACKET_REAUTH +{ + unsigned __int64 tunnelContext; + unsigned long packetId; + TSG_INITIAL_PACKET_TYPE_UNION tsgInitialPacket; +} TSG_PACKET_REAUTH, *PTSG_PACKET_REAUTH; + +typedef union +{ + PTSG_PACKET_HEADER packetHeader; + PTSG_PACKET_VERSIONCAPS packetVersionCaps; + PTSG_PACKET_QUARCONFIGREQUEST packetQuarConfigRequest; + PTSG_PACKET_QUARREQUEST packetQuarRequest; + PTSG_PACKET_RESPONSE packetResponse; + PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse; + PTSG_PACKET_CAPS_RESPONSE packetCapsResponse; + PTSG_PACKET_MSG_REQUEST packetMsgRequest; + PTSG_PACKET_MSG_RESPONSE packetMsgResponse; + PTSG_PACKET_AUTH packetAuth; + PTSG_PACKET_REAUTH packetReauth; +} TSG_PACKET_TYPE_UNION; + +typedef struct _TSG_PACKET +{ + unsigned long packetId; + TSG_PACKET_TYPE_UNION tsgPacket; +} TSG_PACKET, *PTSG_PACKET; + +void Opnum0NotUsedOnWire(void); + +HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, + PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId); + +HRESULT TsProxyAuthorizeTunnel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse); + +HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + unsigned long procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse); + +HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId); + +void Opnum5NotUsedOnWire(void); + +HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context); + +HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context); + +DWORD TsProxySetupReceivePipe(byte pRpcMessage[]); + +DWORD TsProxySendToServer(byte pRpcMessage[]); + boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port); int tsg_write(rdpTsg* tsg, uint8* data, uint32 length); From 9cd6a8e87e5fcb63693b4c4227811c28cb099c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 1 Apr 2012 02:11:07 -0400 Subject: [PATCH 10/47] libfreerdp-core: started annotating TSG packets --- libfreerdp-core/tsg.c | 88 +++++++++++++++++++++++++++++++++++++------ libfreerdp-core/tsg.h | 10 +++-- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 71f41094b..08cdac70a 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -31,6 +31,12 @@ #include "tsg.h" +/** + * RPC Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378623/ + * Remote Procedure Call: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378651/ + * RPC NDR Interface Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802752/ + */ + uint8 tsg_packet1[108] = { 0x43, 0x56, 0x00, 0x00, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, 0x54, 0x43, 0x56, @@ -42,6 +48,40 @@ uint8 tsg_packet1[108] = 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 }; +/** + TsProxyCreateTunnel + + 0x43, 0x56, 0x00, 0x00, packetId (TSG_PACKET_TYPE_VERSIONCAPS) + + TSG_PACKET + 0x43, 0x56, 0x00, 0x00, SwitchValue (TSG_PACKET_TYPE_VERSIONCAPS) + + 0x00, 0x00, 0x02, 0x00, NdrPtr + + 0x52, 0x54, componentId + 0x43, 0x56, packetId + + 0x04, 0x00, 0x02, 0x00, NdrPtr TsgCapsPtr + 0x01, 0x00, 0x00, 0x00, numCapabilities + + 0x01, 0x00, MajorVersion + 0x01, 0x00, MinorVersion + 0x00, 0x00, QuarantineCapabilities + + 0x00, 0x00, alignment pad? + + 0x01, 0x00, 0x00, 0x00, MaximumCount + 0x01, 0x00, 0x00, 0x00, TSG_CAPABILITY_TYPE_NAP + + 0x01, 0x00, 0x00, 0x00, SwitchValue (TSG_NAP_CAPABILITY_QUAR_SOH) + 0x1F, 0x00, 0x00, 0x00, idle value in minutes? + + 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x28, 0x00, 0xDD, 0x65, 0xE2, 0x44, 0xAF, 0x7D, 0xCD, 0x42, 0x85, 0x60, 0x3C, 0xDB, + 0x6E, 0x7A, 0x27, 0x29, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, + 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 + */ + uint8 tsg_packet2[112] = { 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, @@ -53,6 +93,20 @@ uint8 tsg_packet2[112] = 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +/** + TsProxyAuthorizeTunnel + + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x52, 0x51, 0x00, 0x00, + + 0x52, 0x51, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, + 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + */ + uint8 tsg_packet3[40] = { 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, @@ -60,6 +114,18 @@ uint8 tsg_packet3[40] = 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00 }; +/** + TsProxyMakeTunnelCall + + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x01, 0x00, 0x00, 0x00, + + 0x52, 0x47, 0x00, 0x00, + 0x52, 0x47, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00 + */ + uint8 tsg_packet4[48] = { 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, @@ -67,17 +133,22 @@ uint8 tsg_packet4[48] = 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00 }; +/** + TsProxyCreateChannel + + 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, + 0x53, 0x6C, 0x04, 0x33, 0x00, 0x00, 0x02, 0x00, + + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00 + */ + uint8 tsg_packet5[20] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -void Opnum0NotUsedOnWire(void) -{ - return; -} - HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId) { @@ -102,11 +173,6 @@ HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, return 0; } -void Opnum5NotUsedOnWire(void) -{ - return; -} - HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context) { return 0; @@ -277,7 +343,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) status = rpch_read(rpch, data, length); - if(status < 0) + if (status < 0) { printf("rpch_recv failed!\n"); return false; diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 690676d0c..510ba2c0e 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -80,6 +80,12 @@ typedef struct _tsendpointinfo #define TSG_TUNNEL_CALL_ASYNC_MSG_REQUEST 0x00000001 #define TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST 0x00000002 +#define TSG_NAP_CAPABILITY_QUAR_SOH 0x00000001 +#define TSG_NAP_CAPABILITY_IDLE_TIMEOUT 0x00000002 +#define TSG_MESSAGING_CAP_CONSENT_SIGN 0x00000004 +#define TSG_MESSAGING_CAP_SERVICE_MSG 0x00000008 +#define TSG_MESSAGING_CAP_REAUTH 0x00000010 + typedef struct _TSG_PACKET_HEADER { unsigned short ComponentId; @@ -236,8 +242,6 @@ typedef struct _TSG_PACKET TSG_PACKET_TYPE_UNION tsgPacket; } TSG_PACKET, *PTSG_PACKET; -void Opnum0NotUsedOnWire(void); - HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId); @@ -250,8 +254,6 @@ HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId); -void Opnum5NotUsedOnWire(void); - HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context); HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context); From 883b04d51f6c8c702a329f23d67ec0dc11146ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 14 Apr 2012 14:19:31 -0400 Subject: [PATCH 11/47] libfreerdp-core: start HTTP utils --- libfreerdp-core/CMakeLists.txt | 6 +- libfreerdp-core/http.c | 163 ++++++++++++++++++++++++++++++ libfreerdp-core/http.h | 72 +++++++++++++ libfreerdp-core/{rpch.c => rpc.c} | 30 +++++- libfreerdp-core/{rpch.h => rpc.h} | 7 +- libfreerdp-core/tsg.c | 8 +- libfreerdp-core/tsg.h | 2 +- 7 files changed, 279 insertions(+), 9 deletions(-) create mode 100644 libfreerdp-core/http.c create mode 100644 libfreerdp-core/http.h rename libfreerdp-core/{rpch.c => rpc.c} (96%) rename libfreerdp-core/{rpch.h => rpc.h} (99%) diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 4ab065b7c..ca19a0aee 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -35,8 +35,10 @@ set(LIBFREERDP_CORE_SRCS nego.h info.c info.h - rpch.c - rpch.h + http.c + http.h + rpc.c + rpc.h input.c input.h license.c diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c new file mode 100644 index 000000000..241f6e49b --- /dev/null +++ b/libfreerdp-core/http.c @@ -0,0 +1,163 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Hypertext Transfer Protocol (HTTP) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "http.h" + +HttpContext* http_context_new() +{ + HttpContext* http_context = xnew(HttpContext); + + if (http_context != NULL) + { + + } + + return http_context; +} + +void http_context_set_method(HttpContext* http_context, char* method) +{ + http_context->Method = xstrdup(method); +} + +void http_context_set_uri(HttpContext* http_context, char* uri) +{ + http_context->URI = xstrdup(uri); +} + +void http_context_set_user_agent(HttpContext* http_context, char* user_agent) +{ + http_context->UserAgent = xstrdup(user_agent); +} + +void http_context_set_host(HttpContext* http_context, char* host) +{ + http_context->Host = xstrdup(host); +} + +void http_context_set_accept(HttpContext* http_context, char* accept) +{ + http_context->Accept = xstrdup(accept); +} + +void http_context_set_cache_control(HttpContext* http_context, char* cache_control) +{ + http_context->CacheControl = xstrdup(cache_control); +} + +void http_context_set_connection(HttpContext* http_context, char* connection) +{ + http_context->Connection = xstrdup(connection); +} + +void http_context_set_pragma(HttpContext* http_context, char* pragma) +{ + http_context->Pragma = xstrdup(pragma); +} + +void http_context_free(HttpContext* http_context) +{ + if (http_context != NULL) + { + xfree(http_context->UserAgent); + xfree(http_context->Host); + xfree(http_context->Accept); + xfree(http_context->CacheControl); + xfree(http_context->Connection); + xfree(http_context->Pragma); + xfree(http_context); + } +} + +void http_request_set_method(HttpRequest* http_request, char* method) +{ + http_request->Method = xstrdup(method); +} + +void http_request_set_uri(HttpRequest* http_request, char* uri) +{ + http_request->URI = xstrdup(uri); +} + +#define http_encode_line(_str, _fmt, ...) \ + _str = xmalloc(snprintf(NULL, 0, _fmt, ## __VA_ARGS__)); \ + snprintf(_str, snprintf(NULL, 0, _fmt, ## __VA_ARGS__), _fmt, ## __VA_ARGS__); + +STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) +{ + int i; + STREAM* s; + int length = 0; + + http_request->count = 10; + http_request->lines = (char**) xmalloc(sizeof(char*) * http_request->count); + + http_encode_line(http_request->lines[0], "%s %s HTTP/1.1\n", http_request->Method, http_request->URI); + http_encode_line(http_request->lines[1], "Accept: %s\n", http_context->Accept); + http_encode_line(http_request->lines[2], "Cache-Control: %s\n", http_context->CacheControl); + http_encode_line(http_request->lines[3], "Connection: %s\n", http_context->Connection); + http_encode_line(http_request->lines[4], "Content-Length: %d\n", http_request->ContentLength); + http_encode_line(http_request->lines[5], "User-Agent: %s\n", http_context->UserAgent); + http_encode_line(http_request->lines[6], "Host: %s\n", http_context->Host); + http_encode_line(http_request->lines[7], "Pragma: %s\n", http_context->Pragma); + http_encode_line(http_request->lines[8], "Authorization: %s\n", http_request->Authorization); + http_encode_line(http_request->lines[9], "\n\n"); + + for (i = 0; i < http_request->count; i++) + { + length += strlen(http_request->lines[i]); + } + + s = stream_new(length); + + for (i = 0; i < http_request->count; i++) + { + stream_write(s, http_request->lines[i], strlen(http_request->lines[i])); + xfree(http_request->lines[i]); + } + + xfree(http_request->lines); + stream_seal(s); + + return s; +} + +HttpRequest* http_request_new() +{ + HttpRequest* http_request = xnew(HttpRequest); + + if (http_request != NULL) + { + + } + + return http_request; +} + +void http_request_free(HttpRequest* http_request) +{ + if (http_request != NULL) + { + xfree(http_request->Method); + xfree(http_request->URI); + xfree(http_request); + } +} diff --git a/libfreerdp-core/http.h b/libfreerdp-core/http.h new file mode 100644 index 000000000..6c9b007fe --- /dev/null +++ b/libfreerdp-core/http.h @@ -0,0 +1,72 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Hypertext Transfer Protocol (HTTP) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CORE_HTTP_H +#define FREERDP_CORE_HTTP_H + +#include +#include + +struct _http_context +{ + char* Method; + char* URI; + char* UserAgent; + char* Host; + char* Accept; + char* CacheControl; + char* Connection; + char* Pragma; +}; +typedef struct _http_context HttpContext; + +void http_context_set_method(HttpContext* http_context, char* method); +void http_context_set_uri(HttpContext* http_context, char* uri); +void http_context_set_user_agent(HttpContext* http_context, char* user_agent); +void http_context_set_host(HttpContext* http_context, char* host); +void http_context_set_accept(HttpContext* http_context, char* accept); +void http_context_set_cache_control(HttpContext* http_context, char* cache_control); +void http_context_set_connection(HttpContext* http_context, char* connection); +void http_context_set_pragma(HttpContext* http_context, char* pragma); + +HttpContext* http_context_new(); +void http_context_free(HttpContext* http_context); + +struct _http_request +{ + int count; + char** lines; + + char* Method; + char* URI; + char* Authorization; + int ContentLength; + char* Content; +}; +typedef struct _http_request HttpRequest; + +void http_request_set_method(HttpRequest* http_request, char* method); +void http_request_set_uri(HttpRequest* http_request, char* uri); + +STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request); + +HttpRequest* http_request_new(); +void http_request_free(HttpRequest* http_request); + +#endif /* FREERDP_CORE_HTTP_H */ diff --git a/libfreerdp-core/rpch.c b/libfreerdp-core/rpc.c similarity index 96% rename from libfreerdp-core/rpch.c rename to libfreerdp-core/rpc.c index 3a4eb88fc..ed0c77c7c 100644 --- a/libfreerdp-core/rpch.c +++ b/libfreerdp-core/rpc.c @@ -25,7 +25,9 @@ #include -#include "rpch.h" +#include "http.h" + +#include "rpc.h" #define HTTP_STREAM_SIZE 0xFFFF @@ -544,7 +546,7 @@ int rpch_in_write(rdpRpch* rpch, uint8* data, int length) } #ifdef WITH_DEBUG_RPCH - printf("\nrpch_in_send(): length: %d, remaining content length: %d\n", length, http_in->remContentLength); + printf("rpch_in_write() length: %d, remaining content length: %d\n", length, http_in->remContentLength); freerdp_hexdump(data, length); printf("\n"); #endif @@ -1456,6 +1458,30 @@ rdpRpch* rpch_new(rdpSettings* settings) rpch->http_in->state = RPCH_HTTP_DISCONNECTED; rpch->http_out->state = RPCH_HTTP_DISCONNECTED; + rpch->http_in->context = http_context_new(); + http_context_set_method(rpch->http_in->context, "RPC_IN_DATA"); + http_context_set_uri(rpch->http_in->context, "/rpc/rpcproxy.dll?localhost:3388"); + http_context_set_accept(rpch->http_in->context, "application/rpc"); + http_context_set_cache_control(rpch->http_in->context, "no-cache"); + http_context_set_connection(rpch->http_in->context, "Keep-Alive"); + http_context_set_user_agent(rpch->http_in->context, "MSRPC"); + http_context_set_host(rpch->http_in->context, settings->tsg_hostname); + http_context_set_pragma(rpch->http_in->context, + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " + "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); + + rpch->http_out->context = http_context_new(); + http_context_set_method(rpch->http_out->context, "RPC_OUT_DATA"); + http_context_set_uri(rpch->http_out->context, "/rpc/rpcproxy.dll?localhost:3388"); + http_context_set_accept(rpch->http_out->context, "application/rpc"); + http_context_set_cache_control(rpch->http_out->context, "no-cache"); + http_context_set_connection(rpch->http_out->context, "Keep-Alive"); + http_context_set_user_agent(rpch->http_out->context, "MSRPC"); + http_context_set_host(rpch->http_out->context, settings->tsg_hostname); + http_context_set_pragma(rpch->http_out->context, + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " + "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); + rpch->read_buffer = NULL; rpch->write_buffer = NULL; rpch->read_buffer_len = 0; diff --git a/libfreerdp-core/rpch.h b/libfreerdp-core/rpc.h similarity index 99% rename from libfreerdp-core/rpch.h rename to libfreerdp-core/rpc.h index 9e40e18c4..16c1a0852 100644 --- a/libfreerdp-core/rpch.h +++ b/libfreerdp-core/rpc.h @@ -18,8 +18,8 @@ * limitations under the License. */ -#ifndef FREERDP_CORE_RPCH_H -#define FREERDP_CORE_RPCH_H +#ifndef FREERDP_CORE_RPC_H +#define FREERDP_CORE_RPC_H typedef struct rdp_rpch rdpRpch; typedef struct rdp_rpch_http rdpRpchHTTP; @@ -595,6 +595,7 @@ struct rdp_rpch_http RPCH_HTTP_STATE state; int contentLength; int remContentLength; + HttpContext* context; rdpNtlm* ntlm; }; @@ -654,4 +655,4 @@ rdpRpch* rpch_new(rdpSettings* settings); #define DEBUG_RPCH(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif -#endif /* FREERDP_CORE_RPCH_H */ +#endif /* FREERDP_CORE_RPC_H */ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 08cdac70a..760be0017 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -228,6 +228,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + DEBUG_TSG("TsProxyCreateTunnel"); status = rpch_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) @@ -268,6 +269,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * */ + DEBUG_TSG("TsProxyAuthorizeTunnel"); status = rpch_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) @@ -285,7 +287,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) } memcpy(tsg_packet3 + 4, tsg->tunnelContext, 16); - status = rpch_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); /** * OpNum = 3 @@ -298,6 +299,9 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + DEBUG_TSG("TsProxyMakeTunnelCall"); + status = rpch_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); + if (status <= 0) { printf("rpch_write opnum=3 failed!\n"); @@ -332,6 +336,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + DEBUG_TSG("TsProxyCreateChannel"); status = rpch_write(rpch, s_p4->data, s_p4->size, 4); if (status <= 0) @@ -368,6 +373,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + DEBUG_TSG("TsProxySetupReceivePipe"); status = rpch_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 510ba2c0e..80e5dab45 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -24,7 +24,7 @@ typedef struct rdp_tsg rdpTsg; #include "transport.h" -#include "rpch.h" +#include "rpc.h" #include #include From fa7900d293dbe6814484d109f9510a4bedb37245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Apr 2012 16:21:46 -0400 Subject: [PATCH 12/47] libfreerdp-core: start using HTTP utils for NTLM HTTP authentication --- include/freerdp/crypto/crypto.h | 1 + libfreerdp-core/http.c | 278 +++++++++++++++++++++++++++++-- libfreerdp-core/http.h | 31 +++- libfreerdp-core/rpc.c | 287 +++++++++----------------------- libfreerdp-core/rpc.h | 3 +- libfreerdp-core/tsg.c | 12 +- libfreerdp-crypto/crypto.c | 24 +++ 7 files changed, 402 insertions(+), 234 deletions(-) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index de135abda..5cbd074be 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -142,6 +142,7 @@ FREERDP_API void crypto_rsa_private_decrypt(const uint8* input, int length, uint 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 void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length); diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c index 241f6e49b..e055404d9 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp-core/http.c @@ -97,9 +97,19 @@ void http_request_set_uri(HttpRequest* http_request, char* uri) http_request->URI = xstrdup(uri); } +void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme) +{ + http_request->AuthScheme = xstrdup(auth_scheme); +} + +void http_request_set_auth_param(HttpRequest* http_request, char* auth_param) +{ + http_request->AuthParam = xstrdup(auth_param); +} + #define http_encode_line(_str, _fmt, ...) \ - _str = xmalloc(snprintf(NULL, 0, _fmt, ## __VA_ARGS__)); \ - snprintf(_str, snprintf(NULL, 0, _fmt, ## __VA_ARGS__), _fmt, ## __VA_ARGS__); + _str = xmalloc(snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1); \ + snprintf(_str, snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1, _fmt, ## __VA_ARGS__); STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) { @@ -107,34 +117,49 @@ STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) STREAM* s; int length = 0; - http_request->count = 10; + http_request->count = 9; http_request->lines = (char**) xmalloc(sizeof(char*) * http_request->count); - http_encode_line(http_request->lines[0], "%s %s HTTP/1.1\n", http_request->Method, http_request->URI); - http_encode_line(http_request->lines[1], "Accept: %s\n", http_context->Accept); - http_encode_line(http_request->lines[2], "Cache-Control: %s\n", http_context->CacheControl); - http_encode_line(http_request->lines[3], "Connection: %s\n", http_context->Connection); - http_encode_line(http_request->lines[4], "Content-Length: %d\n", http_request->ContentLength); - http_encode_line(http_request->lines[5], "User-Agent: %s\n", http_context->UserAgent); - http_encode_line(http_request->lines[6], "Host: %s\n", http_context->Host); - http_encode_line(http_request->lines[7], "Pragma: %s\n", http_context->Pragma); - http_encode_line(http_request->lines[8], "Authorization: %s\n", http_request->Authorization); - http_encode_line(http_request->lines[9], "\n\n"); + http_encode_line(http_request->lines[0], "%s %s HTTP/1.1", http_request->Method, http_request->URI); + http_encode_line(http_request->lines[1], "Accept: %s", http_context->Accept); + http_encode_line(http_request->lines[2], "Cache-Control: %s", http_context->CacheControl); + http_encode_line(http_request->lines[3], "Connection: %s", http_context->Connection); + http_encode_line(http_request->lines[4], "Content-Length: %d", http_request->ContentLength); + http_encode_line(http_request->lines[5], "User-Agent: %s", http_context->UserAgent); + http_encode_line(http_request->lines[6], "Host: %s", http_context->Host); + http_encode_line(http_request->lines[7], "Pragma: %s", http_context->Pragma); + + if (http_request->Authorization != NULL) + { + http_encode_line(http_request->lines[8], "Authorization: %s", http_request->Authorization); + } + else if ((http_request->AuthScheme != NULL) && (http_request->AuthParam != NULL)) + { + http_encode_line(http_request->lines[8], "Authorization: %s %s", + http_request->AuthScheme, http_request->AuthParam); + } for (i = 0; i < http_request->count; i++) { - length += strlen(http_request->lines[i]); + length += (strlen(http_request->lines[i]) + 1); /* add +1 for each '\n' character */ } + length += 1; /* empty line "\n" at end of header */ + length += 1; /* null terminator */ s = stream_new(length); for (i = 0; i < http_request->count; i++) { stream_write(s, http_request->lines[i], strlen(http_request->lines[i])); + stream_write(s, "\n", 1); xfree(http_request->lines[i]); } + stream_write(s, "\n", 1); xfree(http_request->lines); + + stream_write(s, "\0", 1); /* append null terminator */ + stream_rewind(s, 1); /* don't include null terminator in length */ stream_seal(s); return s; @@ -161,3 +186,228 @@ void http_request_free(HttpRequest* http_request) xfree(http_request); } } + +void http_response_parse_header_status_line(HttpResponse* http_response, char* status_line) +{ + char* separator; + char* status_code; + char* reason_phrase; + + separator = strchr(status_line, ' '); + status_code = separator + 1; + + separator = strchr(status_code, ' '); + reason_phrase = separator + 1; + + *separator = '\0'; + http_response->StatusCode = atoi(status_code); + http_response->ReasonPhrase = xstrdup(reason_phrase); + *separator = ' '; +} + +void http_response_parse_header_field(HttpResponse* http_response, char* name, char* value) +{ + if (strcmp(name, "Content-Length") == 0) + { + http_response->ContentLength = atoi(value); + } + else if (strcmp(name, "Authorization") == 0) + { + char* separator; + + http_response->Authorization = xstrdup(value); + + separator = strchr(value, ' '); + + if (separator != NULL) + { + *separator = '\0'; + http_response->AuthScheme = xstrdup(value); + http_response->AuthParam = xstrdup(separator + 1); + *separator = ' '; + } + } + else if (strcmp(name, "WWW-Authenticate") == 0) + { + char* separator; + + separator = strstr(value, "=\""); + + if (separator != NULL) + { + /* WWW-Authenticate: parameter with spaces="value" */ + return; + } + + separator = strchr(value, ' '); + + if (separator != NULL) + { + /* WWW-Authenticate: NTLM base64token */ + + *separator = '\0'; + http_response->AuthScheme = xstrdup(value); + http_response->AuthParam = xstrdup(separator + 1); + *separator = ' '; + + return; + } + } +} + +void http_response_parse_header(HttpResponse* http_response) +{ + int count; + char* line; + char* name; + char* value; + char* separator; + + http_response_parse_header_status_line(http_response, http_response->lines[0]); + + for (count = 1; count < http_response->count; count++) + { + line = http_response->lines[count]; + + separator = strstr(line, ": "); + + if (separator == NULL) + continue; + + separator[0] = '\0'; + separator[1] = '\0'; + + name = line; + value = separator + 2; + + printf("%s:%s\n", name, value); + + http_response_parse_header_field(http_response, name, value); + + separator[0] = ':'; + separator[1] = ' '; + } +} + +HttpResponse* http_response_recv(rdpTls* tls) +{ + uint8* p; + int nbytes; + int length; + int status; + uint8* buffer; + char* content; + char* header_end; + HttpResponse* http_response; + + nbytes = 0; + length = 2048; + buffer = xmalloc(length); + http_response = http_response_new(); + + p = buffer; + + while (true) + { + status = tls_read(tls, p, length - nbytes); + + if (status > 0) + { + nbytes += status; + p = (uint8*) &buffer[nbytes]; + } + else if (status == 0) + { + continue; + } + else + { + return NULL; + break; + } + + header_end = strstr((char*) buffer, "\r\n\r\n") + 2; + + if (header_end != NULL) + { + int count; + char* line; + + header_end[0] = '\0'; + header_end[1] = '\0'; + content = &header_end[2]; + + count = 0; + line = (char*) buffer; + + while ((line = strstr(line, "\r\n")) != NULL) + { + line++; + count++; + } + + http_response->count = count; + http_response->lines = (char**) xmalloc(sizeof(char*) * http_response->count); + + count = 0; + line = strtok((char*) buffer, "\r\n"); + + while (line != NULL) + { + http_response->lines[count] = xstrdup(line); + line = strtok(NULL, "\r\n"); + count++; + } + + http_response_parse_header(http_response); + + if (http_response->ContentLength > 0) + { + http_response->Content = xstrdup(content); + + printf("Content: (%d)\n%s\n", http_response->ContentLength, + http_response->Content); + } + + break; + } + } + + return http_response; +} + +HttpResponse* http_response_new() +{ + HttpResponse* http_response = xnew(HttpResponse); + + if (http_response != NULL) + { + + } + + return http_response; +} + +void http_response_free(HttpResponse* http_response) +{ + int i; + + if (http_response != NULL) + { + for (i = 0; i < http_response->count; i++) + xfree(http_response->lines[i]); + + xfree(http_response->lines); + + xfree(http_response->ReasonPhrase); + + xfree(http_response->AuthParam); + xfree(http_response->AuthScheme); + xfree(http_response->Authorization); + + if (http_response->ContentLength > 0) + xfree(http_response->Content); + + xfree(http_response); + } +} diff --git a/libfreerdp-core/http.h b/libfreerdp-core/http.h index 6c9b007fe..06f50e97d 100644 --- a/libfreerdp-core/http.h +++ b/libfreerdp-core/http.h @@ -20,7 +20,12 @@ #ifndef FREERDP_CORE_HTTP_H #define FREERDP_CORE_HTTP_H +typedef struct _http_context HttpContext; +typedef struct _http_request HttpRequest; +typedef struct _http_response HttpResponse; + #include +#include #include struct _http_context @@ -34,7 +39,6 @@ struct _http_context char* Connection; char* Pragma; }; -typedef struct _http_context HttpContext; void http_context_set_method(HttpContext* http_context, char* method); void http_context_set_uri(HttpContext* http_context, char* uri); @@ -55,18 +59,41 @@ struct _http_request char* Method; char* URI; + char* AuthScheme; + char* AuthParam; char* Authorization; int ContentLength; char* Content; }; -typedef struct _http_request HttpRequest; void http_request_set_method(HttpRequest* http_request, char* method); void http_request_set_uri(HttpRequest* http_request, char* uri); +void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme); +void http_request_set_auth_param(HttpRequest* http_request, char* auth_param); STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request); HttpRequest* http_request_new(); void http_request_free(HttpRequest* http_request); +struct _http_response +{ + int count; + char** lines; + + int StatusCode; + char* ReasonPhrase; + + char* AuthScheme; + char* AuthParam; + char* Authorization; + int ContentLength; + char* Content; +}; + +HttpResponse* http_response_recv(rdpTls* tls); + +HttpResponse* http_response_new(); +void http_response_free(HttpResponse* http_response); + #endif /* FREERDP_CORE_HTTP_H */ diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index ed0c77c7c..1f391df8b 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -169,62 +169,42 @@ void ntlm_free(rdpNtlm* ntlm) } } -STREAM* rpch_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, uint8* content, int length) +STREAM* rpc_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, uint8* content, int length) { STREAM* s; - char* int_str; - int total_length; - int int_str_length; - int command_length; - rdpSettings* settings; - int tsg_hostname_length; - int ntlm_token_base64_length; - uint8* ntlm_token_base64_data; + char* base64_ntlm_token; + HttpContext* http_context; + HttpRequest* http_request; - settings = rpch->settings; + base64_ntlm_token = crypto_encode_base64(ntlm_token->pvBuffer, ntlm_token->cbBuffer); - command_length = strlen(command); + printf("base64_ntlm_token length:%d\n", strlen(base64_ntlm_token)); - int_str_length = snprintf(NULL, 0, "%d", length); - tsg_hostname_length = strlen(settings->tsg_hostname); + if (strcmp(command, "RPC_IN_DATA") == 0) + http_context = rpch->http_in->context; + else + http_context = rpch->http_out->context; - int_str = xmalloc(int_str_length + 1); - snprintf(int_str, int_str_length + 1, "%d", length); + http_request = http_request_new(); - crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer, &ntlm_token_base64_data, &ntlm_token_base64_length); + http_request->ContentLength = length; - total_length = 55 + 24 + 24 + 23 + 16 + int_str_length + 1 + 18 + 6 + - tsg_hostname_length + 1 + 110 + 20 + ntlm_token_base64_length + 2; + http_request_set_method(http_request, http_context->Method); + http_request_set_uri(http_request, http_context->URI); - s = stream_new(total_length); + http_request_set_auth_scheme(http_request, "NTLM"); + http_request_set_auth_param(http_request, base64_ntlm_token); - stream_write(s, command, command_length); - stream_write(s, " /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 43); - stream_write(s, "Accept: application/rpc\n", 24); - stream_write(s, "Cache-Control: no-cache\n", 24); - stream_write(s, "Connection: Keep-Alive\n", 23); - - stream_write(s, "Content-Length: ", 16); - stream_write(s, int_str, int_str_length); - stream_write(s, "\n", 1); - - stream_write(s, "User-Agent: MSRPC\n", 18); - stream_write(s, "Host: ", 6); - stream_write(s, settings->tsg_hostname, tsg_hostname_length); - stream_write(s, "\n", 1); - stream_write(s, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); - stream_write(s, "Authorization: NTLM ", 20); - stream_write(s, ntlm_token_base64_data, ntlm_token_base64_length); - stream_write(s, "\n\n", 2); - stream_seal(s); + s = http_request_write(http_context, http_request); return s; } -boolean rpch_out_connect_http(rdpRpch* rpch) +boolean rpc_out_connect_http(rdpRpch* rpch) { STREAM* http_stream; STREAM* ntlm_stream; + HttpResponse* http_response; int decoded_ntlm_http_length; int encoded_ntlm_http_length; uint8* decoded_ntlm_http_data = NULL; @@ -236,13 +216,13 @@ boolean rpch_out_connect_http(rdpRpch* rpch) ntlm_stream = stream_new(0); - printf("rpch_out_connect_http\n"); + printf("rpc_out_connect_http\n"); ntlm_client_init(http_out_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_out_ntlm); - http_stream = rpch_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); + http_stream = rpc_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); @@ -256,73 +236,15 @@ boolean rpch_out_connect_http(rdpRpch* rpch) uint8 buffer_byte; http_out->contentLength = 0; - /* Example for how not to do clear code, sorry for that */ - while (true) /* TODO make proper reading */ - { - tls_read(tls_out, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - - if (encoded_ntlm_http_length == -1) - { - uint8* start_of_ntlm_http_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); - - if (start_of_ntlm_http_data != NULL) - { - start_of_ntlm_http_data += 5; - - for (encoded_ntlm_http_length = 0; ; encoded_ntlm_http_length++) - { - tls_read(tls_out, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - - if (start_of_ntlm_http_data[encoded_ntlm_http_length] == '\n') - { - encoded_ntlm_http_length--; /* \r */ - break; - } - } - - encoded_ntlm_http_data = xmalloc(encoded_ntlm_http_length); - memcpy(encoded_ntlm_http_data, start_of_ntlm_http_data, encoded_ntlm_http_length); - } - } - - if (http_out->contentLength == 0) - { - if (strstr((char*) http_stream->data, "Content-Length: ") != NULL) - { - int i = 0; - - while (*(http_stream->p-1) != '\n') - { - tls_read(tls_out, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - i++; - } - - http_out->contentLength = strtol((char*)(http_stream->p - i), NULL, 10); - } - } - - if (*(http_stream->p - 1) == '\n' && *(http_stream->p - 3) == '\n') - { - int i; - - for (i = 0; i < http_out->contentLength; i++) - { - tls_read(tls_out, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - } - - break; - } - } - /* Example end */ + http_response = http_response_recv(tls_out); DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); stream_clear(http_stream); http_stream->p = http_stream->data; + encoded_ntlm_http_data = http_response->AuthParam; + encoded_ntlm_http_length = strlen(encoded_ntlm_http_data); + if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; @@ -336,7 +258,7 @@ boolean rpch_out_connect_http(rdpRpch* rpch) http_out->contentLength = 76; http_out->remContentLength = 76; - http_stream = rpch_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); + http_stream = rpc_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); @@ -351,10 +273,11 @@ boolean rpch_out_connect_http(rdpRpch* rpch) return true; } -boolean rpch_in_connect_http(rdpRpch* rpch) +boolean rpc_in_connect_http(rdpRpch* rpch) { STREAM* ntlm_stream; STREAM* http_stream; + HttpResponse* http_response; int decoded_ntlm_http_length; int encoded_ntlm_http_length; uint8* decoded_ntlm_http_data = NULL; @@ -372,7 +295,7 @@ boolean rpch_in_connect_http(rdpRpch* rpch) ntlm_authenticate(http_in_ntlm); - http_stream = rpch_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); + http_stream = rpc_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_in, http_stream->data, http_stream->size); @@ -388,73 +311,15 @@ boolean rpch_in_connect_http(rdpRpch* rpch) uint8 buffer_byte; http_in->contentLength = 0; - /* Example for how not to do clear code, sorry for that */ - while (true) /* TODO make proper reading */ - { - tls_read(tls_in, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - - if (encoded_ntlm_http_length == -1) - { - uint8* start_of_ntht_data = (uint8*) strstr((char*) http_stream->data, "NTLM "); - - if (start_of_ntht_data != NULL) - { - start_of_ntht_data += 5; - - for (encoded_ntlm_http_length=0;;encoded_ntlm_http_length++) - { - tls_read(tls_in, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - - if (start_of_ntht_data[encoded_ntlm_http_length]=='\n') - { - encoded_ntlm_http_length--; /* \r */ - break; - } - } - - encoded_ntlm_http_data = xmalloc(encoded_ntlm_http_length); - memcpy(encoded_ntlm_http_data, start_of_ntht_data, encoded_ntlm_http_length); - } - } - - if (http_in->contentLength == 0) - { - if (strstr((char*) http_stream->data, "Content-Length: ") != NULL) - { - int i = 0; - - while (*(http_stream->p-1) != '\n') - { - tls_read(tls_in, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - i++; - } - - http_in->contentLength = strtol((char*)(http_stream->p-i), NULL, 10); - } - } - - if (*(http_stream->p - 1) == '\n' && *(http_stream->p - 3) == '\n') - { - int i; - - for(i = 0; i < http_in->contentLength; i++) - { - tls_read(tls_in, &buffer_byte, 1); - stream_write(http_stream, &buffer_byte, 1); - } - - break; - } - } - /* Example end */ + http_response = http_response_recv(tls_in); DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); stream_clear(http_stream); http_stream->p = http_stream->data; + encoded_ntlm_http_data = http_response->AuthParam; + encoded_ntlm_http_length = strlen(encoded_ntlm_http_data); + if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; @@ -468,7 +333,7 @@ boolean rpch_in_connect_http(rdpRpch* rpch) http_in->contentLength = 1073741824; http_in->remContentLength = 1073741824; - http_stream = rpch_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); + http_stream = rpc_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); @@ -486,7 +351,7 @@ boolean rpch_in_connect_http(rdpRpch* rpch) return true; } -int rpch_out_write(rdpRpch* rpch, uint8* data, int length) +int rpc_out_write(rdpRpch* rpch, uint8* data, int length) { int sent = 0; int status = -1; @@ -495,7 +360,7 @@ int rpch_out_write(rdpRpch* rpch, uint8* data, int length) if (http_out->state == RPCH_HTTP_DISCONNECTED) { - if (!rpch_out_connect_http(rpch)) + if (!rpc_out_connect_http(rpch)) return false; } @@ -526,7 +391,7 @@ int rpch_out_write(rdpRpch* rpch, uint8* data, int length) return sent; } -int rpch_in_write(rdpRpch* rpch, uint8* data, int length) +int rpc_in_write(rdpRpch* rpch, uint8* data, int length) { int sent = 0; int status = -1; @@ -535,7 +400,7 @@ int rpch_in_write(rdpRpch* rpch, uint8* data, int length) if (http_in->state == RPCH_HTTP_DISCONNECTED) { - if (!rpch_in_connect_http(rpch)) + if (!rpc_in_connect_http(rpch)) return -1; } @@ -567,14 +432,14 @@ int rpch_in_write(rdpRpch* rpch, uint8* data, int length) return sent; } -uint8* rpch_create_cookie() +uint8* rpc_create_cookie() { uint8* ret = xmalloc(16); RAND_pseudo_bytes(ret, 16); return ret; } -boolean rpch_out_send_CONN_A1(rdpRpch* rpch) +boolean rpc_out_send_CONN_A1(rdpRpch* rpch) { STREAM* pdu = stream_new(76); @@ -597,8 +462,8 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) uint32 rwsCommandType = 0x00000000; uint32 receiveWindowSize = 0x00010000; - rpch->virtualConnectionCookie = rpch_create_cookie(); /* 16 bytes */ - rpch->OUTChannelCookie = rpch_create_cookie(); /* 16 bytes */ + rpch->virtualConnectionCookie = rpc_create_cookie(); /* 16 bytes */ + rpch->OUTChannelCookie = rpc_create_cookie(); /* 16 bytes */ rpch->AwailableWindow = receiveWindowSize; stream_write_uint8(pdu, rpc_vers); @@ -620,14 +485,14 @@ boolean rpch_out_send_CONN_A1(rdpRpch* rpch) stream_write_uint32(pdu, rwsCommandType); stream_write_uint32(pdu, receiveWindowSize); - rpch_out_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_out_write(rpch, pdu->data, stream_get_length(pdu)); stream_free(pdu); return true; } -boolean rpch_in_send_CONN_B1(rdpRpch* rpch) +boolean rpc_in_send_CONN_B1(rdpRpch* rpch) { STREAM* s = stream_new(104); @@ -654,8 +519,8 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) uint32 agidCommandType = 0x0000000c; uint8* AssociationGroupId; - rpch->INChannelCookie = rpch_create_cookie(); /* 16 bytes */ - AssociationGroupId = rpch_create_cookie(); /* 16 bytes */ + rpch->INChannelCookie = rpc_create_cookie(); /* 16 bytes */ + AssociationGroupId = rpc_create_cookie(); /* 16 bytes */ stream_write_uint8(s, rpc_vers); stream_write_uint8(s, rpc_vers_minor); @@ -681,14 +546,14 @@ boolean rpch_in_send_CONN_B1(rdpRpch* rpch) stream_write(s, AssociationGroupId, 16); stream_seal(s); - rpch_in_write(rpch, s->data, s->size); + rpc_in_write(rpch, s->data, s->size); stream_free(s); return true; } -boolean rpch_in_send_keep_alive(rdpRpch* rpch) +boolean rpc_in_send_keep_alive(rdpRpch* rpch) { STREAM* s = stream_new(28); @@ -718,14 +583,14 @@ boolean rpch_in_send_keep_alive(rdpRpch* rpch) stream_write_uint32(s, ckCommandType); stream_write_uint32(s, ClientKeepalive); - rpch_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpch, s->data, stream_get_length(s)); stream_free(s); return true; } -boolean rpch_in_send_bind(rdpRpch* rpch) +boolean rpc_in_send_bind(rdpRpch* rpch) { rpcconn_bind_hdr_t* bind_pdu; rdpSettings* settings = rpch->settings; @@ -844,7 +709,7 @@ boolean rpch_in_send_bind(rdpRpch* rpch) stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); - rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_in_write(rpch, pdu->data, stream_get_length(pdu)); /* TODO there is some allocated memory */ xfree(bind_pdu); @@ -852,7 +717,7 @@ boolean rpch_in_send_bind(rdpRpch* rpch) return true; } -boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) +boolean rpc_in_send_rpc_auth_3(rdpRpch* rpch) { rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); @@ -896,14 +761,14 @@ boolean rpch_in_send_rpc_auth_3(rdpRpch* rpch) stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8); stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length); - rpch_in_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_in_write(rpch, pdu->data, stream_get_length(pdu)); xfree(rpc_auth_3_pdu); return true; } -boolean rpch_in_send_flow_control(rdpRpch* rpch) +boolean rpc_in_send_flow_control(rdpRpch* rpch) { STREAM* s = stream_new(56); @@ -944,14 +809,14 @@ boolean rpch_in_send_flow_control(rdpRpch* rpch) stream_write_uint32(s, aaa); stream_write(s, b, 16); - rpch_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpch, s->data, stream_get_length(s)); stream_free(s); return true; } -boolean rpch_in_send_ping(rdpRpch* rpch) +boolean rpc_in_send_ping(rdpRpch* rpch) { STREAM* s = stream_new(20); @@ -977,14 +842,14 @@ boolean rpch_in_send_ping(rdpRpch* rpch) stream_write_uint16(s, flags); stream_write_uint16(s, num_commands); - rpch_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpch, s->data, stream_get_length(s)); stream_free(s); return true; } -int rpch_out_read_http_header(rdpRpch* rpch) +int rpc_out_read_http_header(rdpRpch* rpch) { int status; STREAM* http_stream; @@ -1040,7 +905,7 @@ int rpch_out_read_http_header(rdpRpch* rpch) return status; } -int rpch_proceed_RTS(rdpRpch* rpch, uint8* pdu, int length) +int rpc_rts_recv(rdpRpch* rpch, uint8* pdu, int length) { int i; uint32 CommandType; @@ -1050,7 +915,7 @@ int rpch_proceed_RTS(rdpRpch* rpch, uint8* pdu, int length) if (flags & RTS_FLAG_PING) { - rpch_in_send_keep_alive(rpch); + rpc_in_send_keep_alive(rpch); return 0; } @@ -1128,7 +993,7 @@ int rpch_proceed_RTS(rdpRpch* rpch, uint8* pdu, int length) return 0; } -int rpch_out_read(rdpRpch* rpch, uint8* data, int length) +int rpc_out_read(rdpRpch* rpch, uint8* data, int length) { int status; uint8* pdu; @@ -1138,11 +1003,11 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) rdpRpchHTTP* http_out = rpch->http_out; if (rpch->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ - rpch_in_send_flow_control(rpch); /* Send FlowControlAck every time AW reaches the half */ + rpc_in_send_flow_control(rpch); /* Send FlowControlAck every time AW reaches the half */ if (http_out->remContentLength <= 0xFFFF) /* TODO make ChannelRecycling */ { - if (rpch_out_read_http_header(rpch) < 0) + if (rpc_out_read_http_header(rpch) < 0) return -1; } @@ -1169,7 +1034,7 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) if (ptype == 0x14) /* RTS PDU */ { - rpch_proceed_RTS(rpch, pdu, frag_length); + rpc_rts_recv(rpch, pdu, frag_length); xfree(pdu); return 0; } @@ -1201,14 +1066,14 @@ int rpch_out_read(rdpRpch* rpch, uint8* data, int length) return frag_length; } -int rpch_out_recv_bind_ack(rdpRpch* rpch) +int rpc_out_recv_bind_ack(rdpRpch* rpch) { uint16 frag_length; uint16 auth_length; STREAM* ntlmssp_stream; int pdu_length = 0x8FFF; /* 32KB buffer */ uint8* pdu = xmalloc(pdu_length); - int status = rpch_out_read(rpch, pdu, pdu_length); + int status = rpc_out_read(rpch, pdu, pdu_length); DEBUG_RPCH("TODO: complete NTLM integration"); @@ -1230,7 +1095,7 @@ int rpch_out_recv_bind_ack(rdpRpch* rpch) return status; } -int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) +int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) { int i; int status = -1; @@ -1297,7 +1162,7 @@ int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) stream_write(pdu, request_pdu->auth_verifier.auth_value, request_pdu->auth_length); - status = rpch_in_write(rpch, pdu->data, pdu->p - pdu->data); + status = rpc_in_write(rpch, pdu->data, pdu->p - pdu->data); xfree(request_pdu->auth_verifier.auth_value); xfree(request_pdu->auth_verifier.auth_pad); @@ -1341,7 +1206,7 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) while (true) { - status = rpch_out_read(rpch, rpch_data, rpch_length); + status = rpc_out_read(rpch, rpch_data, rpch_length); if (status == 0) { @@ -1400,7 +1265,7 @@ boolean rpch_connect(rdpRpch* rpch) uint8* pdu; int pdu_length; - if (!rpch_out_send_CONN_A1(rpch)) + if (!rpc_out_send_CONN_A1(rpch)) { printf("rpch_out_send_CONN_A1 fault!\n"); return false; @@ -1409,32 +1274,32 @@ boolean rpch_connect(rdpRpch* rpch) pdu_length = 0xFFFF; pdu = xmalloc(pdu_length); - status = rpch_out_read(rpch, pdu, pdu_length); + status = rpc_out_read(rpch, pdu, pdu_length); - if (!rpch_in_send_CONN_B1(rpch)) + if (!rpc_in_send_CONN_B1(rpch)) { printf("rpch_out_send_CONN_A1 fault!\n"); return false; } - status = rpch_out_read(rpch, pdu, pdu_length); + status = rpc_out_read(rpch, pdu, pdu_length); /* [MS-RPCH] 3.2.1.5.3.1 Connection Establishment * at this point VirtualChannel is created */ - if (!rpch_in_send_bind(rpch)) + if (!rpc_in_send_bind(rpch)) { printf("rpch_out_send_bind fault!\n"); return false; } - if (!rpch_out_recv_bind_ack(rpch)) + if (!rpc_out_recv_bind_ack(rpch)) { printf("rpch_out_recv_bind_ack fault!\n"); return false; } - if (!rpch_in_send_rpc_auth_3(rpch)) + if (!rpc_in_send_rpc_auth_3(rpch)) { printf("rpch_out_send_rpc_auth_3 fault!\n"); return false; diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 16c1a0852..8a16aa37b 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -25,6 +25,7 @@ typedef struct rdp_rpch rdpRpch; typedef struct rdp_rpch_http rdpRpchHTTP; #include "tcp.h" +#include "http.h" #include #include @@ -640,7 +641,7 @@ void ntlm_free(rdpNtlm* ntlm); boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); boolean rpch_connect(rdpRpch* rpch); -int rpch_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum); +int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum); int rpch_read(rdpRpch* rpch, uint8* data, int length); rdpRpch* rpch_new(rdpSettings* settings); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 760be0017..4e83544f2 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -229,7 +229,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateTunnel"); - status = rpch_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); + status = rpc_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) { @@ -270,7 +270,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyAuthorizeTunnel"); - status = rpch_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); + status = rpc_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) { @@ -300,7 +300,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyMakeTunnelCall"); - status = rpch_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); + status = rpc_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); if (status <= 0) { @@ -337,7 +337,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateChannel"); - status = rpch_write(rpch, s_p4->data, s_p4->size, 4); + status = rpc_write(rpch, s_p4->data, s_p4->size, 4); if (status <= 0) { @@ -374,7 +374,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxySetupReceivePipe"); - status = rpch_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); + status = rpc_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) { @@ -411,7 +411,7 @@ int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) memcpy(tsg_pkg + 32 + length, pp, 8); - status = rpch_write(tsg->rpch, tsg_pkg, tsg_length, opnum); + status = rpc_write(tsg->rpch, tsg_pkg, tsg_length, opnum); xfree(tsg_pkg); stream_free(s); diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp-crypto/crypto.c index d84e0e68c..12a1d6c53 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp-crypto/crypto.c @@ -531,6 +531,30 @@ void crypto_base64_encode(uint8* data, int length, uint8** enc_data, int* res_le BIO_free_all(b64); } +char* crypto_encode_base64(uint8* data, int length) +{ + BIO* bmem; + BIO* b64; + BUF_MEM *bptr; + char* base64_string; + + 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); + + base64_string = xmalloc(bptr->length); + memcpy(base64_string, bptr->data, bptr->length - 1); + base64_string[bptr->length] = '\0'; + + BIO_free_all(b64); + + return base64_string; +} + void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length) { BIO *b64, *bmem; From 2df6c9c3167d87a53002e9b47eb6229afdb2b769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 18 Apr 2012 01:53:12 -0400 Subject: [PATCH 13/47] libfreerdp-core: RPCH cleanup --- libfreerdp-core/rpc.c | 448 +++++++++++++++++++----------------------- libfreerdp-core/rpc.h | 42 ++-- libfreerdp-core/tsg.c | 16 +- libfreerdp-core/tsg.h | 2 +- 4 files changed, 230 insertions(+), 278 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 1f391df8b..926ed043d 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -31,12 +31,12 @@ #define HTTP_STREAM_SIZE 0xFFFF -boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out) +boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out) { - rpch->tcp_in = tcp_in; - rpch->tcp_out = tcp_out; - rpch->tls_in = tls_in; - rpch->tls_out = tls_out; + rpc->tcp_in = tcp_in; + rpc->tcp_out = tcp_out; + rpc->tls_in = tls_in; + rpc->tls_out = tls_out; return true; } @@ -169,7 +169,7 @@ void ntlm_free(rdpNtlm* ntlm) } } -STREAM* rpc_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, uint8* content, int length) +STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, uint8* content, int length) { STREAM* s; char* base64_ntlm_token; @@ -178,12 +178,10 @@ STREAM* rpc_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, base64_ntlm_token = crypto_encode_base64(ntlm_token->pvBuffer, ntlm_token->cbBuffer); - printf("base64_ntlm_token length:%d\n", strlen(base64_ntlm_token)); - if (strcmp(command, "RPC_IN_DATA") == 0) - http_context = rpch->http_in->context; + http_context = rpc->http_in->context; else - http_context = rpch->http_out->context; + http_context = rpc->http_out->context; http_request = http_request_new(); @@ -200,7 +198,7 @@ STREAM* rpc_ntlm_http_data(rdpRpch* rpch, char* command, SecBuffer* ntlm_token, return s; } -boolean rpc_out_connect_http(rdpRpch* rpch) +boolean rpc_out_connect_http(rdpRpc* rpc) { STREAM* http_stream; STREAM* ntlm_stream; @@ -209,9 +207,9 @@ boolean rpc_out_connect_http(rdpRpch* rpch) int encoded_ntlm_http_length; uint8* decoded_ntlm_http_data = NULL; uint8* encoded_ntlm_http_data = NULL; - rdpTls* tls_out = rpch->tls_out; - rdpSettings* settings = rpch->settings; - rdpRpchHTTP* http_out = rpch->http_out; + rdpTls* tls_out = rpc->tls_out; + rdpSettings* settings = rpc->settings; + rdpRpcHTTP* http_out = rpc->http_out; rdpNtlm* http_out_ntlm = http_out->ntlm; ntlm_stream = stream_new(0); @@ -222,9 +220,9 @@ boolean rpc_out_connect_http(rdpRpch* rpch) ntlm_authenticate(http_out_ntlm); - http_stream = rpc_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); + http_stream = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); - DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + DEBUG_RPC("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); http_stream = stream_new(0xFFFF); stream_clear(http_stream); @@ -233,17 +231,16 @@ boolean rpc_out_connect_http(rdpRpch* rpch) encoded_ntlm_http_length = -1; xfree(encoded_ntlm_http_data); encoded_ntlm_http_data = NULL; - uint8 buffer_byte; http_out->contentLength = 0; http_response = http_response_recv(tls_out); - DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); + DEBUG_RPC("\nRecv:\n%s\n", http_stream->data); stream_clear(http_stream); http_stream->p = http_stream->data; - encoded_ntlm_http_data = http_response->AuthParam; - encoded_ntlm_http_length = strlen(encoded_ntlm_http_data); + encoded_ntlm_http_data = (uint8*) http_response->AuthParam; + encoded_ntlm_http_length = strlen((char*) encoded_ntlm_http_data); if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; @@ -258,9 +255,9 @@ boolean rpc_out_connect_http(rdpRpch* rpch) http_out->contentLength = 76; http_out->remContentLength = 76; - http_stream = rpc_ntlm_http_data(rpch, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); + http_stream = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); - DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + DEBUG_RPC("\nSend:\n%s\n", http_stream->data); tls_write(tls_out, http_stream->data, http_stream->size); stream_clear(http_stream); @@ -268,12 +265,12 @@ boolean rpc_out_connect_http(rdpRpch* rpch) xfree(encoded_ntlm_http_data); /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ - http_out->state = RPCH_HTTP_SENDING; + http_out->state = RPC_HTTP_SENDING; return true; } -boolean rpc_in_connect_http(rdpRpch* rpch) +boolean rpc_in_connect_http(rdpRpc* rpc) { STREAM* ntlm_stream; STREAM* http_stream; @@ -282,22 +279,22 @@ boolean rpc_in_connect_http(rdpRpch* rpch) int encoded_ntlm_http_length; uint8* decoded_ntlm_http_data = NULL; uint8* encoded_ntlm_http_data = NULL; - rdpTls* tls_in = rpch->tls_in; - rdpSettings* settings = rpch->settings; - rdpRpchHTTP* http_in = rpch->http_in; + rdpTls* tls_in = rpc->tls_in; + rdpSettings* settings = rpc->settings; + rdpRpcHTTP* http_in = rpc->http_in; rdpNtlm* http_in_ntlm = http_in->ntlm; ntlm_stream = stream_new(0); - printf("rpch_in_connect_http\n"); + printf("rpc_in_connect_http\n"); ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_in_ntlm); - http_stream = rpc_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); + http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); - DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + DEBUG_RPC("Send:\n%s\n", http_stream->data); tls_write(tls_in, http_stream->data, http_stream->size); http_stream = stream_new(0xFFFF); stream_clear(http_stream); @@ -308,17 +305,16 @@ boolean rpc_in_connect_http(rdpRpch* rpch) encoded_ntlm_http_length = -1; xfree(encoded_ntlm_http_data); encoded_ntlm_http_data = NULL; - uint8 buffer_byte; http_in->contentLength = 0; http_response = http_response_recv(tls_in); - DEBUG_RPCH("\nRecv:\n%s\n", http_stream->data); + DEBUG_RPC("Recv:\n%s\n", http_stream->data); stream_clear(http_stream); http_stream->p = http_stream->data; - encoded_ntlm_http_data = http_response->AuthParam; - encoded_ntlm_http_length = strlen(encoded_ntlm_http_data); + encoded_ntlm_http_data = (uint8*) http_response->AuthParam; + encoded_ntlm_http_length = strlen((char*) encoded_ntlm_http_data); if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ return false; @@ -333,9 +329,9 @@ boolean rpc_in_connect_http(rdpRpch* rpch) http_in->contentLength = 1073741824; http_in->remContentLength = 1073741824; - http_stream = rpc_ntlm_http_data(rpch, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); + http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); - DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); + DEBUG_RPC("Send:\n%s\n", http_stream->data); tls_write(tls_in, http_stream->data, http_stream->size); @@ -346,32 +342,32 @@ boolean rpc_in_connect_http(rdpRpch* rpch) xfree(encoded_ntlm_http_data); /* At this point IN connection is ready to send CONN/B1 and start with sending data */ - http_in->state = RPCH_HTTP_SENDING; + http_in->state = RPC_HTTP_SENDING; return true; } -int rpc_out_write(rdpRpch* rpch, uint8* data, int length) +int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { int sent = 0; int status = -1; - rdpRpchHTTP* http_out = rpch->http_out; - rdpTls* tls_out = rpch->tls_out; + rdpRpcHTTP* http_out = rpc->http_out; + rdpTls* tls_out = rpc->tls_out; - if (http_out->state == RPCH_HTTP_DISCONNECTED) + if (http_out->state == RPC_HTTP_DISCONNECTED) { - if (!rpc_out_connect_http(rpch)) + if (!rpc_out_connect_http(rpc)) return false; } if (http_out->remContentLength < length) { - printf("RPCH Error: HTTP frame is over.\n"); + printf("RPC Error: HTTP frame is over.\n"); return -1; /* TODO ChannelRecycling */ } -#ifdef WITH_DEBUG_RPCH - printf("rpch_out_write(): length: %d\n", length); +#ifdef WITH_DEBUG_RPC + printf("rpc_out_write(): length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif @@ -391,34 +387,34 @@ int rpc_out_write(rdpRpch* rpch, uint8* data, int length) return sent; } -int rpc_in_write(rdpRpch* rpch, uint8* data, int length) +int rpc_in_write(rdpRpc* rpc, uint8* data, int length) { int sent = 0; int status = -1; - rdpRpchHTTP* http_in = rpch->http_in; - rdpTls* tls_in = rpch->tls_in; + rdpRpcHTTP* http_in = rpc->http_in; + rdpTls* tls_in = rpc->tls_in; - if (http_in->state == RPCH_HTTP_DISCONNECTED) + if (http_in->state == RPC_HTTP_DISCONNECTED) { - if (!rpc_in_connect_http(rpch)) + if (!rpc_in_connect_http(rpc)) return -1; } if (http_in->remContentLength < length) { - printf("RPCH Error: HTTP frame is over.\n"); + printf("RPC Error: HTTP frame is over.\n"); return -1;/* TODO ChannelRecycling */ } -#ifdef WITH_DEBUG_RPCH - printf("rpch_in_write() length: %d, remaining content length: %d\n", length, http_in->remContentLength); +#ifdef WITH_DEBUG_RPC + printf("rpc_in_write() length: %d, remaining content length: %d\n", length, http_in->remContentLength); freerdp_hexdump(data, length); printf("\n"); #endif while (sent < length) { - status = tls_write(tls_in, data+sent, length-sent); + status = tls_write(tls_in, data + sent, length - sent); if (status <= 0) return status; /* TODO no idea how to handle errors */ @@ -426,7 +422,7 @@ int rpc_in_write(rdpRpch* rpch, uint8* data, int length) sent += status; } - rpch->BytesSent += sent; + rpc->BytesSent += sent; http_in->remContentLength -= sent; return sent; @@ -439,11 +435,11 @@ uint8* rpc_create_cookie() return ret; } -boolean rpc_out_send_CONN_A1(rdpRpch* rpch) +boolean rpc_out_send_CONN_A1(rdpRpc* rpc) { STREAM* pdu = stream_new(76); - DEBUG_RPCH("Sending CONN_A1"); + DEBUG_RPC("Sending CONN_A1"); uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; @@ -462,9 +458,9 @@ boolean rpc_out_send_CONN_A1(rdpRpch* rpch) uint32 rwsCommandType = 0x00000000; uint32 receiveWindowSize = 0x00010000; - rpch->virtualConnectionCookie = rpc_create_cookie(); /* 16 bytes */ - rpch->OUTChannelCookie = rpc_create_cookie(); /* 16 bytes */ - rpch->AwailableWindow = receiveWindowSize; + rpc->virtualConnectionCookie = rpc_create_cookie(); /* 16 bytes */ + rpc->OUTChannelCookie = rpc_create_cookie(); /* 16 bytes */ + rpc->AwailableWindow = receiveWindowSize; stream_write_uint8(pdu, rpc_vers); stream_write_uint8(pdu, rpc_vers_minor); @@ -479,24 +475,24 @@ boolean rpc_out_send_CONN_A1(rdpRpch* rpch) stream_write_uint32(pdu, vCommandType); stream_write_uint32(pdu, Version); stream_write_uint32(pdu, vccCommandType); - stream_write(pdu, rpch->virtualConnectionCookie, 16); + stream_write(pdu, rpc->virtualConnectionCookie, 16); stream_write_uint32(pdu, occCommandType); - stream_write(pdu, rpch->OUTChannelCookie, 16); + stream_write(pdu, rpc->OUTChannelCookie, 16); stream_write_uint32(pdu, rwsCommandType); stream_write_uint32(pdu, receiveWindowSize); - rpc_out_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_out_write(rpc, pdu->data, stream_get_length(pdu)); stream_free(pdu); return true; } -boolean rpc_in_send_CONN_B1(rdpRpch* rpch) +boolean rpc_in_send_CONN_B1(rdpRpc* rpc) { STREAM* s = stream_new(104); - DEBUG_RPCH("Sending CONN_B1"); + DEBUG_RPC("Sending CONN_B1"); uint8 rpc_vers = 0x05; uint8 rpc_vers_minor = 0x00; @@ -519,7 +515,7 @@ boolean rpc_in_send_CONN_B1(rdpRpch* rpch) uint32 agidCommandType = 0x0000000c; uint8* AssociationGroupId; - rpch->INChannelCookie = rpc_create_cookie(); /* 16 bytes */ + rpc->INChannelCookie = rpc_create_cookie(); /* 16 bytes */ AssociationGroupId = rpc_create_cookie(); /* 16 bytes */ stream_write_uint8(s, rpc_vers); @@ -535,9 +531,9 @@ boolean rpc_in_send_CONN_B1(rdpRpch* rpch) stream_write_uint32(s, vCommandType); stream_write_uint32(s, Version); stream_write_uint32(s, vccCommandType); - stream_write(s, rpch->virtualConnectionCookie, 16); + stream_write(s, rpc->virtualConnectionCookie, 16); stream_write_uint32(s, iccCommandType); - stream_write(s, rpch->INChannelCookie, 16); + stream_write(s, rpc->INChannelCookie, 16); stream_write_uint32(s, clCommandType); stream_write_uint32(s, ChannelLifetime); stream_write_uint32(s, ckCommandType); @@ -546,14 +542,14 @@ boolean rpc_in_send_CONN_B1(rdpRpch* rpch) stream_write(s, AssociationGroupId, 16); stream_seal(s); - rpc_in_write(rpch, s->data, s->size); + rpc_in_write(rpc, s->data, s->size); stream_free(s); return true; } -boolean rpc_in_send_keep_alive(rdpRpch* rpch) +boolean rpc_in_send_keep_alive(rdpRpc* rpc) { STREAM* s = stream_new(28); @@ -583,30 +579,31 @@ boolean rpc_in_send_keep_alive(rdpRpch* rpch) stream_write_uint32(s, ckCommandType); stream_write_uint32(s, ClientKeepalive); - rpc_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpc, s->data, stream_get_length(s)); stream_free(s); return true; } -boolean rpc_in_send_bind(rdpRpch* rpch) +boolean rpc_in_send_bind(rdpRpc* rpc) { + STREAM* pdu; rpcconn_bind_hdr_t* bind_pdu; - rdpSettings* settings = rpch->settings; + rdpSettings* settings = rpc->settings; STREAM* ntlm_stream = stream_new(0xFFFF); /* TODO: Set NTLMv2 + DO_NOT_SEAL, DomainName = GatewayName? */ - rpch->ntlm = ntlm_new(); + rpc->ntlm = ntlm_new(); - DEBUG_RPCH("TODO: complete NTLM integration"); + DEBUG_RPC("TODO: complete NTLM integration"); - ntlm_client_init(rpch->ntlm, settings->username, settings->password, settings->domain); + ntlm_client_init(rpc->ntlm, settings->username, settings->password, settings->domain); - ntlm_authenticate(rpch->ntlm); - ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; + ntlm_authenticate(rpc->ntlm); + ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer; bind_pdu = xnew(rpcconn_bind_hdr_t); bind_pdu->rpc_vers = 5; @@ -694,7 +691,7 @@ boolean rpc_in_send_bind(rdpRpch* rpch) stream_free(ntlm_stream); - STREAM* pdu = stream_new(bind_pdu->frag_length); + pdu = stream_new(bind_pdu->frag_length); stream_write(pdu, bind_pdu, 24); stream_write(pdu, &bind_pdu->p_context_elem, 4); @@ -709,7 +706,7 @@ boolean rpc_in_send_bind(rdpRpch* rpch) stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); - rpc_in_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_in_write(rpc, pdu->data, stream_get_length(pdu)); /* TODO there is some allocated memory */ xfree(bind_pdu); @@ -717,14 +714,14 @@ boolean rpc_in_send_bind(rdpRpch* rpch) return true; } -boolean rpc_in_send_rpc_auth_3(rdpRpch* rpch) +boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) { rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); - ntlm_authenticate(rpch->ntlm); - ntlm_stream->size = rpch->ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = rpch->ntlm->outputBuffer.pvBuffer; + ntlm_authenticate(rpc->ntlm); + ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; + ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer; rpc_auth_3_pdu = xnew(rpcconn_rpc_auth_3_hdr_t); rpc_auth_3_pdu->rpc_vers = 5; @@ -761,14 +758,14 @@ boolean rpc_in_send_rpc_auth_3(rdpRpch* rpch) stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8); stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length); - rpc_in_write(rpch, pdu->data, stream_get_length(pdu)); + rpc_in_write(rpc, pdu->data, stream_get_length(pdu)); xfree(rpc_auth_3_pdu); return true; } -boolean rpc_in_send_flow_control(rdpRpch* rpch) +boolean rpc_in_send_flow_control(rdpRpc* rpc) { STREAM* s = stream_new(56); @@ -786,11 +783,11 @@ boolean rpc_in_send_flow_control(rdpRpch* rpch) uint32 ckCommandType = 0x0000000d; uint32 ClientKeepalive = 0x00000003; uint32 a = 0x00000001; - uint32 aa = rpch->BytesReceived; + uint32 aa = rpc->BytesReceived; uint32 aaa = 0x00010000; - rpch->AwailableWindow = aaa; - b = rpch->OUTChannelCookie; + rpc->AwailableWindow = aaa; + b = rpc->OUTChannelCookie; stream_write_uint8(s, rpc_vers); stream_write_uint8(s, rpc_vers_minor); @@ -809,14 +806,14 @@ boolean rpc_in_send_flow_control(rdpRpch* rpch) stream_write_uint32(s, aaa); stream_write(s, b, 16); - rpc_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpc, s->data, stream_get_length(s)); stream_free(s); return true; } -boolean rpc_in_send_ping(rdpRpch* rpch) +boolean rpc_in_send_ping(rdpRpc* rpc) { STREAM* s = stream_new(20); @@ -842,70 +839,25 @@ boolean rpc_in_send_ping(rdpRpch* rpch) stream_write_uint16(s, flags); stream_write_uint16(s, num_commands); - rpc_in_write(rpch, s->data, stream_get_length(s)); + rpc_in_write(rpc, s->data, stream_get_length(s)); stream_free(s); return true; } -int rpc_out_read_http_header(rdpRpch* rpch) +int rpc_out_read_http_header(rdpRpc* rpc) { - int status; - STREAM* http_stream; - rdpTls* tls_out = rpch->tls_out; - rdpRpchHTTP* http_out = rpch->http_out; + int status = 0; + HttpResponse* http_response; + rdpTls* tls_out = rpc->tls_out; - http_stream = stream_new(1024); /* hope the header will not be larger */ - http_out->contentLength = 0; - - while (true) /* TODO make proper reading */ - { - status = tls_read(tls_out, stream_get_tail(http_stream), 1); - - if (status < 0) - return status; - - stream_seek(http_stream, 1); - - if (http_out->contentLength == 0) - { - if (strstr((char*) stream_get_head(http_stream), "Content-Length:") != NULL) - { - int i = 0; - - while (*(stream_get_tail(http_stream) - 1) != '\n') - { - status = tls_read(tls_out, stream_get_tail(http_stream), 1); - - if (status < 0) - return status; - - stream_seek(http_stream, 1); - i++; - - if (*(stream_get_tail(http_stream) - 1) == ' ') - i--; - } - - http_out->contentLength = strtol((char*) (stream_get_tail(http_stream) - i), NULL, 10); - http_out->remContentLength = http_out->contentLength; - } - } - - if (*(stream_get_tail(http_stream) - 1) == '\n' && *(stream_get_tail(http_stream) - 3) == '\n') - { - break; - } - } - - DEBUG_RPCH("\nRecv HTTP header:\n%s", stream_get_head(http_stream)); - stream_free(http_stream); + http_response = http_response_recv(tls_out); return status; } -int rpc_rts_recv(rdpRpch* rpch, uint8* pdu, int length) +int rpc_rts_recv(rdpRpc* rpc, uint8* pdu, int length) { int i; uint32 CommandType; @@ -915,7 +867,7 @@ int rpc_rts_recv(rdpRpch* rpch, uint8* pdu, int length) if (flags & RTS_FLAG_PING) { - rpc_in_send_keep_alive(rpch); + rpc_in_send_keep_alive(rpc); return 0; } @@ -993,21 +945,21 @@ int rpc_rts_recv(rdpRpch* rpch, uint8* pdu, int length) return 0; } -int rpc_out_read(rdpRpch* rpch, uint8* data, int length) +int rpc_out_read(rdpRpc* rpc, uint8* data, int length) { int status; uint8* pdu; uint8 ptype; uint16 frag_length; - rdpTls* tls_out = rpch->tls_out; - rdpRpchHTTP* http_out = rpch->http_out; + rdpTls* tls_out = rpc->tls_out; + rdpRpcHTTP* http_out = rpc->http_out; - if (rpch->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ - rpc_in_send_flow_control(rpch); /* Send FlowControlAck every time AW reaches the half */ + if (rpc->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ + rpc_in_send_flow_control(rpc); /* Send FlowControlAck every time AW reaches the half */ if (http_out->remContentLength <= 0xFFFF) /* TODO make ChannelRecycling */ { - if (rpc_out_read_http_header(rpch) < 0) + if (rpc_out_read_http_header(rpc) < 0) return -1; } @@ -1034,31 +986,31 @@ int rpc_out_read(rdpRpch* rpch, uint8* data, int length) if (ptype == 0x14) /* RTS PDU */ { - rpc_rts_recv(rpch, pdu, frag_length); + rpc_rts_recv(rpc, pdu, frag_length); xfree(pdu); return 0; } else { - rpch->BytesReceived += frag_length; /* RTS PDUs are not subjects for FlowControl */ - rpch->AwailableWindow -= frag_length; + rpc->BytesReceived += frag_length; /* RTS PDUs are not subjects for FlowControl */ + rpc->AwailableWindow -= frag_length; } http_out->remContentLength -= frag_length; if (length < frag_length) { - printf("rcph_out_read(): Error! Given buffer is to small. Received data fits not in.\n"); + printf("rpc_out_read(): Error! Given buffer is to small. Received data fits not in.\n"); xfree(pdu); return -1; /* TODO add buffer for storing remaining data for the next read in case destination buffer is too small */ } memcpy(data, pdu, frag_length); -#ifdef WITH_DEBUG_RPCH - //printf("\nrpch_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); - //freerdp_hexdump(data, frag_length); - //printf("\n"); +#ifdef WITH_DEBUG_RPC + printf("rpc_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); + freerdp_hexdump(data, frag_length); + printf("\n"); #endif xfree(pdu); @@ -1066,16 +1018,16 @@ int rpc_out_read(rdpRpch* rpch, uint8* data, int length) return frag_length; } -int rpc_out_recv_bind_ack(rdpRpch* rpch) +int rpc_out_recv_bind_ack(rdpRpc* rpc) { uint16 frag_length; uint16 auth_length; STREAM* ntlmssp_stream; int pdu_length = 0x8FFF; /* 32KB buffer */ uint8* pdu = xmalloc(pdu_length); - int status = rpc_out_read(rpch, pdu, pdu_length); + int status = rpc_out_read(rpc, pdu, pdu_length); - DEBUG_RPCH("TODO: complete NTLM integration"); + DEBUG_RPC("TODO: complete NTLM integration"); if (status > 0) { @@ -1086,7 +1038,7 @@ int rpc_out_recv_bind_ack(rdpRpch* rpch) stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); ntlmssp_stream->p = ntlmssp_stream->data; - //ntlmssp_recv(rpch->ntlmssp, ntlmssp_stream); + //ntlmssp_recv(rpc->ntlmssp, ntlmssp_stream); stream_free(ntlmssp_stream); } @@ -1095,7 +1047,7 @@ int rpc_out_recv_bind_ack(rdpRpch* rpch) return status; } -int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) +int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) { int i; int status = -1; @@ -1117,12 +1069,12 @@ int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) request_pdu->packed_drep[3] = 0x00; request_pdu->frag_length = 24 + length + auth_pad_length + 8 + 16; request_pdu->auth_length = 16; - request_pdu->call_id = ++rpch->call_id; + request_pdu->call_id = ++rpc->call_id; /* opnum=8 means [MS-TSGU] TsProxySetupRecievePipe, save call_id for checking pipe responses */ if (opnum == 8) - rpch->pipe_call_id = rpch->call_id; + rpc->pipe_call_id = rpc->call_id; request_pdu->alloc_hint = length; request_pdu->p_cont_id = 0x0000; @@ -1156,13 +1108,13 @@ int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) rdpMsg.data = pdu->data; rdpMsg.length = stream_get_length(pdu); - DEBUG_RPCH("TODO: complete NTLM integration"); + DEBUG_RPC("TODO: complete NTLM integration"); - //ntlmssp_encrypt_message(rpch->ntlmssp, &rdpMsg, NULL, request_pdu->auth_verifier.auth_value); + //ntlmssp_encrypt_message(rpc->ntlmssp, &rdpMsg, NULL, request_pdu->auth_verifier.auth_value); stream_write(pdu, request_pdu->auth_verifier.auth_value, request_pdu->auth_length); - status = rpc_in_write(rpch, pdu->data, pdu->p - pdu->data); + status = rpc_in_write(rpc, pdu->data, pdu->p - pdu->data); xfree(request_pdu->auth_verifier.auth_value); xfree(request_pdu->auth_verifier.auth_pad); @@ -1170,14 +1122,14 @@ int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum) if (status < 0) { - printf("rpch_write(): Error! rcph_in_write returned negative value.\n"); + printf("rpc_write(): Error! rcph_in_write returned negative value.\n"); return status; } return length; } -int rpch_read(rdpRpch* rpch, uint8* data, int length) +int rpc_read(rdpRpc* rpc, uint8* data, int length) { int status; int read = 0; @@ -1186,47 +1138,47 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) uint16 auth_length; uint8 auth_pad_length; uint32 call_id = -1; - int rpch_length = length + 0xFF; - uint8* rpch_data = xmalloc(rpch_length); + int rpc_length = length + 0xFF; + uint8* rpc_data = xmalloc(rpc_length); - if (rpch->read_buffer_len > 0) + if (rpc->read_buffer_len > 0) { - if (rpch->read_buffer_len > length) + if (rpc->read_buffer_len > length) { /*TODO fix read_buffer is too long problem */ - printf("ERROR! RPCH Stores data in read_buffer fits not in data on rpch_read.\n"); + printf("ERROR! RPCH Stores data in read_buffer fits not in data on rpc_read.\n"); return -1; } - memcpy(data, rpch->read_buffer, rpch->read_buffer_len); - read += rpch->read_buffer_len; - xfree(rpch->read_buffer); - rpch->read_buffer_len = 0; + memcpy(data, rpc->read_buffer, rpc->read_buffer_len); + read += rpc->read_buffer_len; + xfree(rpc->read_buffer); + rpc->read_buffer_len = 0; } while (true) { - status = rpc_out_read(rpch, rpch_data, rpch_length); + status = rpc_out_read(rpc, rpc_data, rpc_length); if (status == 0) { - xfree(rpch_data); + xfree(rpc_data); return read; } else if (status < 0) { - printf("\nError! rpch_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", - rpch->BytesSent, rpch->BytesReceived); + printf("\nError! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", + rpc->BytesSent, rpc->BytesReceived); - xfree(rpch_data); + xfree(rpc_data); return status; } - frag_length = *(uint16*)(rpch_data + 8); - auth_length = *(uint16*)(rpch_data + 10); - call_id = *(uint32*)(rpch_data + 12); - status = *(uint32*)(rpch_data + 16); /* alloc_hint */ - auth_pad_length = *(rpch_data + frag_length - auth_length - 6); /* -6 = -8 + 2 (sec_trailer + 2) */ + frag_length = *(uint16*)(rpc_data + 8); + auth_length = *(uint16*)(rpc_data + 10); + call_id = *(uint32*)(rpc_data + 12); + status = *(uint32*)(rpc_data + 16); /* alloc_hint */ + auth_pad_length = *(rpc_data + frag_length - auth_length - 6); /* -6 = -8 + 2 (sec_trailer + 2) */ /* data_length must be calculated because alloc_hint carries size of more than one pdu */ data_length = frag_length - auth_length - 24 - 8 - auth_pad_length; /* 24 is header; 8 is sec_trailer */ @@ -1236,15 +1188,15 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) if (read + data_length > length) /* if read data is greater then given buffer */ { - rpch->read_buffer_len = read + data_length - length; - rpch->read_buffer = xmalloc(rpch->read_buffer_len); + rpc->read_buffer_len = read + data_length - length; + rpc->read_buffer = xmalloc(rpc->read_buffer_len); - data_length -= rpch->read_buffer_len; + data_length -= rpc->read_buffer_len; - memcpy(rpch->read_buffer, rpch_data + 24 + data_length, rpch->read_buffer_len); + memcpy(rpc->read_buffer, rpc_data + 24 + data_length, rpc->read_buffer_len); } - memcpy(data + read, rpch_data + 24, data_length); + memcpy(data + read, rpc_data + 24, data_length); read += data_length; @@ -1254,54 +1206,54 @@ int rpch_read(rdpRpch* rpch, uint8* data, int length) break; } - xfree(rpch_data); + xfree(rpc_data); return read; } -boolean rpch_connect(rdpRpch* rpch) +boolean rpc_connect(rdpRpc* rpc) { int status; uint8* pdu; int pdu_length; - if (!rpc_out_send_CONN_A1(rpch)) + if (!rpc_out_send_CONN_A1(rpc)) { - printf("rpch_out_send_CONN_A1 fault!\n"); + printf("rpc_out_send_CONN_A1 fault!\n"); return false; } pdu_length = 0xFFFF; pdu = xmalloc(pdu_length); - status = rpc_out_read(rpch, pdu, pdu_length); + status = rpc_out_read(rpc, pdu, pdu_length); - if (!rpc_in_send_CONN_B1(rpch)) + if (!rpc_in_send_CONN_B1(rpc)) { - printf("rpch_out_send_CONN_A1 fault!\n"); + printf("rpc_out_send_CONN_A1 fault!\n"); return false; } - status = rpc_out_read(rpch, pdu, pdu_length); + status = rpc_out_read(rpc, pdu, pdu_length); /* [MS-RPCH] 3.2.1.5.3.1 Connection Establishment * at this point VirtualChannel is created */ - if (!rpc_in_send_bind(rpch)) + if (!rpc_in_send_bind(rpc)) { - printf("rpch_out_send_bind fault!\n"); + printf("rpc_out_send_bind fault!\n"); return false; } - if (!rpc_out_recv_bind_ack(rpch)) + if (!rpc_out_recv_bind_ack(rpc)) { - printf("rpch_out_recv_bind_ack fault!\n"); + printf("rpc_out_recv_bind_ack fault!\n"); return false; } - if (!rpc_in_send_rpc_auth_3(rpch)) + if (!rpc_in_send_rpc_auth_3(rpc)) { - printf("rpch_out_send_rpc_auth_3 fault!\n"); + printf("rpc_out_send_rpc_auth_3 fault!\n"); return false; } @@ -1309,60 +1261,60 @@ boolean rpch_connect(rdpRpch* rpch) return true; } -rdpRpch* rpch_new(rdpSettings* settings) +rdpRpc* rpc_new(rdpSettings* settings) { - rdpRpch* rpch = (rdpRpch*) xnew(rdpRpch); + rdpRpc* rpc = (rdpRpc*) xnew(rdpRpc); - if (rpch != NULL) + if (rpc != NULL) { - rpch->http_in = (rdpRpchHTTP*) xnew(rdpRpchHTTP); - rpch->http_out = (rdpRpchHTTP*) xnew(rdpRpchHTTP); + rpc->http_in = (rdpRpcHTTP*) xnew(rdpRpcHTTP); + rpc->http_out = (rdpRpcHTTP*) xnew(rdpRpcHTTP); - rpch->http_in->ntlm = ntlm_new(); - rpch->http_out->ntlm = ntlm_new(); - rpch->http_in->state = RPCH_HTTP_DISCONNECTED; - rpch->http_out->state = RPCH_HTTP_DISCONNECTED; + rpc->http_in->ntlm = ntlm_new(); + rpc->http_out->ntlm = ntlm_new(); + rpc->http_in->state = RPC_HTTP_DISCONNECTED; + rpc->http_out->state = RPC_HTTP_DISCONNECTED; - rpch->http_in->context = http_context_new(); - http_context_set_method(rpch->http_in->context, "RPC_IN_DATA"); - http_context_set_uri(rpch->http_in->context, "/rpc/rpcproxy.dll?localhost:3388"); - http_context_set_accept(rpch->http_in->context, "application/rpc"); - http_context_set_cache_control(rpch->http_in->context, "no-cache"); - http_context_set_connection(rpch->http_in->context, "Keep-Alive"); - http_context_set_user_agent(rpch->http_in->context, "MSRPC"); - http_context_set_host(rpch->http_in->context, settings->tsg_hostname); - http_context_set_pragma(rpch->http_in->context, + rpc->http_in->context = http_context_new(); + http_context_set_method(rpc->http_in->context, "RPC_IN_DATA"); + http_context_set_uri(rpc->http_in->context, "/rpc/rpcproxy.dll?localhost:3388"); + http_context_set_accept(rpc->http_in->context, "application/rpc"); + http_context_set_cache_control(rpc->http_in->context, "no-cache"); + http_context_set_connection(rpc->http_in->context, "Keep-Alive"); + http_context_set_user_agent(rpc->http_in->context, "MSRPC"); + http_context_set_host(rpc->http_in->context, settings->tsg_hostname); + http_context_set_pragma(rpc->http_in->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); - rpch->http_out->context = http_context_new(); - http_context_set_method(rpch->http_out->context, "RPC_OUT_DATA"); - http_context_set_uri(rpch->http_out->context, "/rpc/rpcproxy.dll?localhost:3388"); - http_context_set_accept(rpch->http_out->context, "application/rpc"); - http_context_set_cache_control(rpch->http_out->context, "no-cache"); - http_context_set_connection(rpch->http_out->context, "Keep-Alive"); - http_context_set_user_agent(rpch->http_out->context, "MSRPC"); - http_context_set_host(rpch->http_out->context, settings->tsg_hostname); - http_context_set_pragma(rpch->http_out->context, + rpc->http_out->context = http_context_new(); + http_context_set_method(rpc->http_out->context, "RPC_OUT_DATA"); + http_context_set_uri(rpc->http_out->context, "/rpc/rpcproxy.dll?localhost:3388"); + http_context_set_accept(rpc->http_out->context, "application/rpc"); + http_context_set_cache_control(rpc->http_out->context, "no-cache"); + http_context_set_connection(rpc->http_out->context, "Keep-Alive"); + http_context_set_user_agent(rpc->http_out->context, "MSRPC"); + http_context_set_host(rpc->http_out->context, settings->tsg_hostname); + http_context_set_pragma(rpc->http_out->context, "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); - rpch->read_buffer = NULL; - rpch->write_buffer = NULL; - rpch->read_buffer_len = 0; - rpch->write_buffer_len = 0; + rpc->read_buffer = NULL; + rpc->write_buffer = NULL; + rpc->read_buffer_len = 0; + rpc->write_buffer_len = 0; - rpch->BytesReceived = 0; - rpch->AwailableWindow = 0; - rpch->BytesSent = 0; - rpch->RecAwailableWindow = 0; + rpc->BytesReceived = 0; + rpc->AwailableWindow = 0; + rpc->BytesSent = 0; + rpc->RecAwailableWindow = 0; - rpch->settings = settings; + rpc->settings = settings; - rpch->ntlm = ntlm_new(); + rpc->ntlm = ntlm_new(); - rpch->call_id = 0; + rpc->call_id = 0; } - return rpch; + return rpc; } diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 8a16aa37b..8c4cade61 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -21,8 +21,8 @@ #ifndef FREERDP_CORE_RPC_H #define FREERDP_CORE_RPC_H -typedef struct rdp_rpch rdpRpch; -typedef struct rdp_rpch_http rdpRpchHTTP; +typedef struct rdp_rpc rdpRpc; +typedef struct rdp_rpc_http rdpRpcHTTP; #include "tcp.h" #include "http.h" @@ -583,24 +583,24 @@ struct rdp_ntlm }; typedef struct rdp_ntlm rdpNtlm; -enum _RPCH_HTTP_STATE +enum _RPC_HTTP_STATE { - RPCH_HTTP_DISCONNECTED = 0, - RPCH_HTTP_SENDING = 1, - RPCH_HTTP_RECIEVING = 2 + RPC_HTTP_DISCONNECTED = 0, + RPC_HTTP_SENDING = 1, + RPC_HTTP_RECEIVING = 2 }; -typedef enum _RPCH_HTTP_STATE RPCH_HTTP_STATE; +typedef enum _RPC_HTTP_STATE RPC_HTTP_STATE; -struct rdp_rpch_http +struct rdp_rpc_http { - RPCH_HTTP_STATE state; + RPC_HTTP_STATE state; int contentLength; int remContentLength; HttpContext* context; rdpNtlm* ntlm; }; -struct rdp_rpch +struct rdp_rpc { rdpTcp* tcp_in; rdpTcp* tcp_out; @@ -608,8 +608,8 @@ struct rdp_rpch rdpTls* tls_out; rdpNtlm* ntlm; - rdpRpchHTTP* http_in; - rdpRpchHTTP* http_out; + rdpRpcHTTP* http_in; + rdpRpcHTTP* http_out; UNICONV* uniconv; rdpSettings* settings; @@ -638,22 +638,22 @@ void ntlm_client_uninit(rdpNtlm* ntlm); rdpNtlm* ntlm_new(); void ntlm_free(rdpNtlm* ntlm); -boolean rpch_attach(rdpRpch* rpch, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); -boolean rpch_connect(rdpRpch* rpch); +boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); +boolean rpc_connect(rdpRpc* rpc); -int rpc_write(rdpRpch* rpch, uint8* data, int length, uint16 opnum); -int rpch_read(rdpRpch* rpch, uint8* data, int length); +int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); +int rpc_read(rdpRpc* rpc, uint8* data, int length); -rdpRpch* rpch_new(rdpSettings* settings); +rdpRpc* rpc_new(rdpSettings* settings); #ifdef WITH_DEBUG_TSG -#define WITH_DEBUG_RPCH +#define WITH_DEBUG_RPC #endif -#ifdef WITH_DEBUG_RPCH -#define DEBUG_RPCH(fmt, ...) DEBUG_CLASS(RPCH, fmt, ## __VA_ARGS__) +#ifdef WITH_DEBUG_RPC +#define DEBUG_RPC(fmt, ...) DEBUG_CLASS(RPC, fmt, ## __VA_ARGS__) #else -#define DEBUG_RPCH(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_RPC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif #endif /* FREERDP_CORE_RPC_H */ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 4e83544f2..c9042be46 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -197,19 +197,19 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { int status = -1; - rdpRpch* rpch = tsg->rpch; + rdpRpc* rpch = tsg->rpch; rdpTransport* transport = tsg->transport; uint32 length; uint8* data; - if (!rpch_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) + if (!rpc_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) { printf("rpch_attach failed!\n"); return false; } - if (!rpch_connect(rpch)) + if (!rpc_connect(rpch)) { printf("rpch_connect failed!\n"); return false; @@ -239,7 +239,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) length = 0x8FFF; data = xmalloc(length); - status = rpch_read(rpch, data, length); + status = rpc_read(rpch, data, length); if (status <= 0) { @@ -278,7 +278,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - status = rpch_read(rpch, data, length); + status = rpc_read(rpch, data, length); if (status <= 0) { @@ -346,7 +346,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) } xfree(dest_addr_unic); - status = rpch_read(rpch, data, length); + status = rpc_read(rpch, data, length); if (status < 0) { @@ -429,7 +429,7 @@ int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) { int status; - status = rpch_read(tsg->rpch, data, length); + status = rpc_read(tsg->rpch, data, length); return status; } @@ -440,7 +440,7 @@ rdpTsg* tsg_new(rdpSettings* settings) tsg = (rdpTsg*) xzalloc(sizeof(rdpTsg)); tsg->settings = settings; - tsg->rpch = rpch_new(settings); + tsg->rpch = rpc_new(settings); return tsg; } diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 80e5dab45..18a477929 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -36,7 +36,7 @@ typedef struct rdp_tsg rdpTsg; struct rdp_tsg { - rdpRpch* rpch; + rdpRpc* rpch; uint8* tunnelContext; uint8* channelContext; rdpSettings* settings; From 88b8380b4cd5cbb57da6a94eaa54d4a1b4be5ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 18 Apr 2012 02:28:05 -0400 Subject: [PATCH 14/47] libfreerdp-core: simplify HTTPS sending --- include/freerdp/crypto/tls.h | 2 + libfreerdp-core/http.c | 7 +- libfreerdp-core/rpc.c | 183 ++++++++--------------------------- libfreerdp-core/rpc.h | 2 - libfreerdp-crypto/tls.c | 24 +++++ 5 files changed, 66 insertions(+), 152 deletions(-) diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index 0b2931e1f..fa9f155d7 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -49,6 +49,8 @@ FREERDP_API boolean tls_disconnect(rdpTls* tls); FREERDP_API int tls_read(rdpTls* tls, uint8* data, int length); FREERDP_API int tls_write(rdpTls* tls, uint8* data, int length); +FREERDP_API int tls_write_all(rdpTls* tls, uint8* data, int length); + FREERDP_API boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname); FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint); FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count); diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c index e055404d9..de982d6c4 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp-core/http.c @@ -280,8 +280,6 @@ void http_response_parse_header(HttpResponse* http_response) name = line; value = separator + 2; - printf("%s:%s\n", name, value); - http_response_parse_header_field(http_response, name, value); separator[0] = ':'; @@ -301,7 +299,7 @@ HttpResponse* http_response_recv(rdpTls* tls) HttpResponse* http_response; nbytes = 0; - length = 2048; + length = 0xFFFF; buffer = xmalloc(length); http_response = http_response_new(); @@ -364,9 +362,6 @@ HttpResponse* http_response_recv(rdpTls* tls) if (http_response->ContentLength > 0) { http_response->Content = xstrdup(content); - - printf("Content: (%d)\n%s\n", http_response->ContentLength, - http_response->Content); } break; diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 926ed043d..a247adfed 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -200,69 +200,39 @@ STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, ui boolean rpc_out_connect_http(rdpRpc* rpc) { - STREAM* http_stream; - STREAM* ntlm_stream; + STREAM* s; HttpResponse* http_response; - int decoded_ntlm_http_length; - int encoded_ntlm_http_length; - uint8* decoded_ntlm_http_data = NULL; - uint8* encoded_ntlm_http_data = NULL; + int ntlm_token_length; + uint8* ntlm_token_data = NULL; rdpTls* tls_out = rpc->tls_out; rdpSettings* settings = rpc->settings; rdpRpcHTTP* http_out = rpc->http_out; rdpNtlm* http_out_ntlm = http_out->ntlm; - ntlm_stream = stream_new(0); - - printf("rpc_out_connect_http\n"); - ntlm_client_init(http_out_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_out_ntlm); - http_stream = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); + s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); - DEBUG_RPC("\nSend:\n%s\n", http_stream->data); - tls_write(tls_out, http_stream->data, http_stream->size); - http_stream = stream_new(0xFFFF); - stream_clear(http_stream); - http_stream->p = http_stream->data; - - encoded_ntlm_http_length = -1; - xfree(encoded_ntlm_http_data); - encoded_ntlm_http_data = NULL; - http_out->contentLength = 0; + DEBUG_RPC("%s", s->data); + tls_write_all(tls_out, s->data, s->size); http_response = http_response_recv(tls_out); - DEBUG_RPC("\nRecv:\n%s\n", http_stream->data); - stream_clear(http_stream); - http_stream->p = http_stream->data; + crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), + &ntlm_token_data, &ntlm_token_length); - encoded_ntlm_http_data = (uint8*) http_response->AuthParam; - encoded_ntlm_http_length = strlen((char*) encoded_ntlm_http_data); - - if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ - return false; - - crypto_base64_decode(encoded_ntlm_http_data, encoded_ntlm_http_length, &decoded_ntlm_http_data, &decoded_ntlm_http_length); - - http_out_ntlm->inputBuffer.pvBuffer = decoded_ntlm_http_data; - http_out_ntlm->inputBuffer.cbBuffer = decoded_ntlm_http_length; + http_out_ntlm->inputBuffer.pvBuffer = ntlm_token_data; + http_out_ntlm->inputBuffer.cbBuffer = ntlm_token_length; ntlm_authenticate(http_out_ntlm); - http_out->contentLength = 76; - http_out->remContentLength = 76; + s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 76); - http_stream = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, http_out->contentLength); + DEBUG_RPC("%s", s->data); + tls_write_all(tls_out, s->data, s->size); - DEBUG_RPC("\nSend:\n%s\n", http_stream->data); - tls_write(tls_out, http_stream->data, http_stream->size); - stream_clear(http_stream); - - xfree(decoded_ntlm_http_data); - xfree(encoded_ntlm_http_data); /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ http_out->state = RPC_HTTP_SENDING; @@ -272,74 +242,39 @@ boolean rpc_out_connect_http(rdpRpc* rpc) boolean rpc_in_connect_http(rdpRpc* rpc) { - STREAM* ntlm_stream; STREAM* http_stream; HttpResponse* http_response; - int decoded_ntlm_http_length; - int encoded_ntlm_http_length; - uint8* decoded_ntlm_http_data = NULL; - uint8* encoded_ntlm_http_data = NULL; + int ntlm_token_length; + uint8* ntlm_token_data = NULL; rdpTls* tls_in = rpc->tls_in; rdpSettings* settings = rpc->settings; rdpRpcHTTP* http_in = rpc->http_in; rdpNtlm* http_in_ntlm = http_in->ntlm; - ntlm_stream = stream_new(0); - - printf("rpc_in_connect_http\n"); - ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); ntlm_authenticate(http_in_ntlm); http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); - DEBUG_RPC("Send:\n%s\n", http_stream->data); - tls_write(tls_in, http_stream->data, http_stream->size); - http_stream = stream_new(0xFFFF); - stream_clear(http_stream); - http_stream->p = http_stream->data; - - xfree(decoded_ntlm_http_data); - - encoded_ntlm_http_length = -1; - xfree(encoded_ntlm_http_data); - encoded_ntlm_http_data = NULL; - http_in->contentLength = 0; + DEBUG_RPC("%s", http_stream->data); + tls_write_all(tls_in, http_stream->data, http_stream->size); http_response = http_response_recv(tls_in); - DEBUG_RPC("Recv:\n%s\n", http_stream->data); - stream_clear(http_stream); - http_stream->p = http_stream->data; + crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), + &ntlm_token_data, &ntlm_token_length); - encoded_ntlm_http_data = (uint8*) http_response->AuthParam; - encoded_ntlm_http_length = strlen((char*) encoded_ntlm_http_data); - - if (encoded_ntlm_http_length == 0) /* No NTLM data was found */ - return false; - - crypto_base64_decode(encoded_ntlm_http_data, encoded_ntlm_http_length, &decoded_ntlm_http_data, &decoded_ntlm_http_length); - - http_in_ntlm->inputBuffer.pvBuffer = decoded_ntlm_http_data; - http_in_ntlm->inputBuffer.cbBuffer = decoded_ntlm_http_length; + http_in_ntlm->inputBuffer.pvBuffer = ntlm_token_data; + http_in_ntlm->inputBuffer.cbBuffer = ntlm_token_length; ntlm_authenticate(http_in_ntlm); - http_in->contentLength = 1073741824; - http_in->remContentLength = 1073741824; + http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 1073741824); - http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, http_in->contentLength); + DEBUG_RPC("%s", http_stream->data); + tls_write_all(tls_in, http_stream->data, http_stream->size); - DEBUG_RPC("Send:\n%s\n", http_stream->data); - - tls_write(tls_in, http_stream->data, http_stream->size); - - stream_clear(http_stream); - http_stream->p = http_stream->data; - - xfree(decoded_ntlm_http_data); - xfree(encoded_ntlm_http_data); /* At this point IN connection is ready to send CONN/B1 and start with sending data */ http_in->state = RPC_HTTP_SENDING; @@ -349,10 +284,9 @@ boolean rpc_in_connect_http(rdpRpc* rpc) int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { - int sent = 0; - int status = -1; - rdpRpcHTTP* http_out = rpc->http_out; + int status; rdpTls* tls_out = rpc->tls_out; + rdpRpcHTTP* http_out = rpc->http_out; if (http_out->state == RPC_HTTP_DISCONNECTED) { @@ -360,39 +294,22 @@ int rpc_out_write(rdpRpc* rpc, uint8* data, int length) return false; } - if (http_out->remContentLength < length) - { - printf("RPC Error: HTTP frame is over.\n"); - return -1; /* TODO ChannelRecycling */ - } - #ifdef WITH_DEBUG_RPC printf("rpc_out_write(): length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif - while (sent < length) - { - status = tls_write(tls_out, data + sent, length - sent); + status = tls_write_all(tls_out, data, length); - if (status <= 0) - return status; /* TODO no idea how to handle errors */ - - sent += status; - } - - http_out->remContentLength -= sent; - - return sent; + return status; } int rpc_in_write(rdpRpc* rpc, uint8* data, int length) { - int sent = 0; - int status = -1; - rdpRpcHTTP* http_in = rpc->http_in; + int status; rdpTls* tls_in = rpc->tls_in; + rdpRpcHTTP* http_in = rpc->http_in; if (http_in->state == RPC_HTTP_DISCONNECTED) { @@ -400,32 +317,18 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length) return -1; } - if (http_in->remContentLength < length) - { - printf("RPC Error: HTTP frame is over.\n"); - return -1;/* TODO ChannelRecycling */ - } - #ifdef WITH_DEBUG_RPC - printf("rpc_in_write() length: %d, remaining content length: %d\n", length, http_in->remContentLength); + printf("rpc_in_write() length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif - while (sent < length) - { - status = tls_write(tls_in, data + sent, length - sent); + status = tls_write_all(tls_in, data, length); - if (status <= 0) - return status; /* TODO no idea how to handle errors */ + if (status > 0) + rpc->BytesSent += status; - sent += status; - } - - rpc->BytesSent += sent; - http_in->remContentLength -= sent; - - return sent; + return status; } uint8* rpc_create_cookie() @@ -716,6 +619,7 @@ boolean rpc_in_send_bind(rdpRpc* rpc) boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) { + STREAM* pdu; rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); @@ -748,7 +652,7 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) stream_free(ntlm_stream); - STREAM* pdu = stream_new(rpc_auth_3_pdu->frag_length); + pdu = stream_new(rpc_auth_3_pdu->frag_length); stream_write(pdu, rpc_auth_3_pdu, 20); @@ -952,17 +856,10 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) uint8 ptype; uint16 frag_length; rdpTls* tls_out = rpc->tls_out; - rdpRpcHTTP* http_out = rpc->http_out; if (rpc->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ rpc_in_send_flow_control(rpc); /* Send FlowControlAck every time AW reaches the half */ - if (http_out->remContentLength <= 0xFFFF) /* TODO make ChannelRecycling */ - { - if (rpc_out_read_http_header(rpc) < 0) - return -1; - } - pdu = xmalloc(0xFFFF); status = tls_read(tls_out, pdu, 10); @@ -996,8 +893,6 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) rpc->AwailableWindow -= frag_length; } - http_out->remContentLength -= frag_length; - if (length < frag_length) { printf("rpc_out_read(): Error! Given buffer is to small. Received data fits not in.\n"); @@ -1008,7 +903,7 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) memcpy(data, pdu, frag_length); #ifdef WITH_DEBUG_RPC - printf("rpc_out_recv(): length: %d, remaining content length: %d\n", frag_length, http_out->remContentLength); + printf("rpc_out_recv(): length: %d\n", frag_length); freerdp_hexdump(data, frag_length); printf("\n"); #endif @@ -1167,7 +1062,7 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) } else if (status < 0) { - printf("\nError! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", + printf("Error! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", rpc->BytesSent, rpc->BytesReceived); xfree(rpc_data); diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 8c4cade61..e55fa15f7 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -594,8 +594,6 @@ typedef enum _RPC_HTTP_STATE RPC_HTTP_STATE; struct rdp_rpc_http { RPC_HTTP_STATE state; - int contentLength; - int remContentLength; HttpContext* context; rdpNtlm* ntlm; }; diff --git a/libfreerdp-crypto/tls.c b/libfreerdp-crypto/tls.c index 26b1e1edc..13c160f0f 100644 --- a/libfreerdp-crypto/tls.c +++ b/libfreerdp-crypto/tls.c @@ -255,6 +255,30 @@ int tls_write(rdpTls* tls, uint8* data, int length) return status; } + +int tls_write_all(rdpTls* tls, uint8* data, int length) +{ + int status; + int sent = 0; + + do + { + status = tls_write(tls, &data[sent], length - sent); + + if (status > 0) + sent += status; + + if (sent >= length) + break; + } + while (status >= 0); + + if (status > 0) + return length; + else + return status; +} + static void tls_errors(const char *prefix) { unsigned long error; From 19614129413f96fcad65e0066d257640705463ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Apr 2012 11:29:53 -0400 Subject: [PATCH 15/47] libfreerdp-core: fix NTLM HTTP authentication --- libfreerdp-core/http.c | 19 ++++++--- libfreerdp-core/rpc.c | 45 ++++++++++++++++----- libfreerdp-core/tsg.c | 80 +++++++++++++++++++------------------- libfreerdp-core/tsg.h | 2 +- libfreerdp-crypto/crypto.c | 2 +- 5 files changed, 90 insertions(+), 58 deletions(-) diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c index de982d6c4..ddba2c17c 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp-core/http.c @@ -121,13 +121,13 @@ STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) http_request->lines = (char**) xmalloc(sizeof(char*) * http_request->count); http_encode_line(http_request->lines[0], "%s %s HTTP/1.1", http_request->Method, http_request->URI); - http_encode_line(http_request->lines[1], "Accept: %s", http_context->Accept); - http_encode_line(http_request->lines[2], "Cache-Control: %s", http_context->CacheControl); - http_encode_line(http_request->lines[3], "Connection: %s", http_context->Connection); - http_encode_line(http_request->lines[4], "Content-Length: %d", http_request->ContentLength); + http_encode_line(http_request->lines[1], "Cache-Control: %s", http_context->CacheControl); + http_encode_line(http_request->lines[2], "Connection: %s", http_context->Connection); + http_encode_line(http_request->lines[3], "Pragma: %s", http_context->Pragma); + http_encode_line(http_request->lines[4], "Accept: %s", http_context->Accept); http_encode_line(http_request->lines[5], "User-Agent: %s", http_context->UserAgent); - http_encode_line(http_request->lines[6], "Host: %s", http_context->Host); - http_encode_line(http_request->lines[7], "Pragma: %s", http_context->Pragma); + http_encode_line(http_request->lines[6], "Content-Length: %d", http_request->ContentLength); + http_encode_line(http_request->lines[7], "Host: %s", http_context->Host); if (http_request->Authorization != NULL) { @@ -366,6 +366,13 @@ HttpResponse* http_response_recv(rdpTls* tls) break; } + + if ((length - nbytes) <= 0) + { + length *= 2; + buffer = xrealloc(buffer, length); + p = (uint8*) &buffer[nbytes]; + } } return http_response; diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index a247adfed..a63e1f0f6 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -113,6 +113,14 @@ boolean ntlm_authenticate(rdpNtlm* ntlm) ntlm->outputBuffer.cbBuffer = ntlm->cbMaxToken; ntlm->outputBuffer.pvBuffer = xmalloc(ntlm->outputBuffer.cbBuffer); + if (ntlm->haveInputBuffer) + { + ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION; + ntlm->inputBufferDesc.cBuffers = 1; + ntlm->inputBufferDesc.pBuffers = &ntlm->inputBuffer; + ntlm->inputBuffer.BufferType = SECBUFFER_TOKEN; + } + status = ntlm->table->InitializeSecurityContext(&ntlm->credentials, (ntlm->haveContext) ? &ntlm->context : NULL, NULL, ntlm->fContextReq, 0, SECURITY_NATIVE_DREP, @@ -120,6 +128,14 @@ boolean ntlm_authenticate(rdpNtlm* ntlm) 0, &ntlm->context, &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration); +#ifdef WITH_DEBUG_RPC + if (ntlm->haveInputBuffer) + { + printf("NTLM Token (%d)\n", ntlm->inputBuffer.cbBuffer); + freerdp_hexdump(ntlm->inputBuffer.pvBuffer, ntlm->inputBuffer.cbBuffer); + } +#endif + if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) { if (ntlm->table->CompleteAuthToken != NULL) @@ -176,6 +192,11 @@ STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, ui HttpContext* http_context; HttpRequest* http_request; +#ifdef WITH_DEBUG_RPC + printf("NTLM Token (%d):\n", ntlm_token->cbBuffer); + freerdp_hexdump(ntlm_token->pvBuffer, ntlm_token->cbBuffer); +#endif + base64_ntlm_token = crypto_encode_base64(ntlm_token->pvBuffer, ntlm_token->cbBuffer); if (strcmp(command, "RPC_IN_DATA") == 0) @@ -209,7 +230,7 @@ boolean rpc_out_connect_http(rdpRpc* rpc) rdpRpcHTTP* http_out = rpc->http_out; rdpNtlm* http_out_ntlm = http_out->ntlm; - ntlm_client_init(http_out_ntlm, settings->username, settings->password, settings->domain); + ntlm_client_init(http_out_ntlm, settings->username, settings->domain, settings->password); ntlm_authenticate(http_out_ntlm); @@ -251,7 +272,7 @@ boolean rpc_in_connect_http(rdpRpc* rpc) rdpRpcHTTP* http_in = rpc->http_in; rdpNtlm* http_in_ntlm = http_in->ntlm; - ntlm_client_init(http_in_ntlm, settings->username, settings->password, settings->domain); + ntlm_client_init(http_in_ntlm, settings->username, settings->domain, settings->password); ntlm_authenticate(http_in_ntlm); @@ -270,7 +291,7 @@ boolean rpc_in_connect_http(rdpRpc* rpc) ntlm_authenticate(http_in_ntlm); - http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 1073741824); + http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0x40000000); DEBUG_RPC("%s", http_stream->data); tls_write_all(tls_in, http_stream->data, http_stream->size); @@ -902,8 +923,14 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) memcpy(data, pdu, frag_length); + if (strncmp((char*) pdu, "HTTP", 4) == 0) + { + printf("Unexpected HTTP response, likely caused by an NTLM HTTP authentication failure\n"); + return -1; + } + #ifdef WITH_DEBUG_RPC - printf("rpc_out_recv(): length: %d\n", frag_length); + printf("rpc_out_read(): length: %d\n", frag_length); freerdp_hexdump(data, frag_length); printf("\n"); #endif @@ -1040,8 +1067,8 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) { if (rpc->read_buffer_len > length) { - /*TODO fix read_buffer is too long problem */ - printf("ERROR! RPCH Stores data in read_buffer fits not in data on rpc_read.\n"); + /* TODO fix read_buffer is too long problem */ + printf("ERROR! RPC Stores data in read_buffer fits not in data on rpc_read.\n"); return -1; } @@ -1179,8 +1206,7 @@ rdpRpc* rpc_new(rdpSettings* settings) http_context_set_user_agent(rpc->http_in->context, "MSRPC"); http_context_set_host(rpc->http_in->context, settings->tsg_hostname); http_context_set_pragma(rpc->http_in->context, - "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " - "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); rpc->http_out->context = http_context_new(); http_context_set_method(rpc->http_out->context, "RPC_OUT_DATA"); @@ -1191,8 +1217,7 @@ rdpRpc* rpc_new(rdpSettings* settings) http_context_set_user_agent(rpc->http_out->context, "MSRPC"); http_context_set_host(rpc->http_out->context, settings->tsg_hostname); http_context_set_pragma(rpc->http_out->context, - "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, " - "SessionId=33ad20ac-7469-4f63-946d-113eac21a23c"); + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); rpc->read_buffer = NULL; rpc->write_buffer = NULL; diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index c9042be46..7c28db3ac 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -195,27 +195,25 @@ DWORD TsProxySendToServer(byte pRpcMessage[]) boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { + uint8* data; + uint32 length; int status = -1; - - rdpRpc* rpch = tsg->rpch; + rdpRpc* rpc = tsg->rpc; rdpTransport* transport = tsg->transport; - uint32 length; - uint8* data; - - if (!rpc_attach(rpch, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) + if (!rpc_attach(rpc, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) { - printf("rpch_attach failed!\n"); + printf("rpc_attach failed!\n"); return false; } - if (!rpc_connect(rpch)) + if (!rpc_connect(rpc)) { - printf("rpch_connect failed!\n"); + printf("rpc_connect failed!\n"); return false; } - DEBUG_TSG("rpch_connect success"); + DEBUG_TSG("rpc_connect success"); /** * OpNum = 1 @@ -229,21 +227,21 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateTunnel"); - status = rpc_write(rpch, tsg_packet1, sizeof(tsg_packet1), 1); + status = rpc_write(rpc, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) { - printf("rpch_write opnum=1 failed!\n"); + printf("rpc_write opnum=1 failed!\n"); return false; } length = 0x8FFF; data = xmalloc(length); - status = rpc_read(rpch, data, length); + status = rpc_read(rpc, data, length); if (status <= 0) { - printf("rpch_recv failed!\n"); + printf("rpc_recv failed!\n"); return false; } @@ -270,19 +268,19 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyAuthorizeTunnel"); - status = rpc_write(rpch, tsg_packet2, sizeof(tsg_packet2), 2); + status = rpc_write(rpc, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) { - printf("rpch_write opnum=2 failed!\n"); + printf("rpc_write opnum=2 failed!\n"); return false; } - status = rpc_read(rpch, data, length); + status = rpc_read(rpc, data, length); if (status <= 0) { - printf("rpch_recv failed!\n"); + printf("rpc_recv failed!\n"); return false; } @@ -300,11 +298,11 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyMakeTunnelCall"); - status = rpc_write(rpch, tsg_packet3, sizeof(tsg_packet3), 3); + status = rpc_write(rpc, tsg_packet3, sizeof(tsg_packet3), 3); if (status <= 0) { - printf("rpch_write opnum=3 failed!\n"); + printf("rpc_write opnum=3 failed!\n"); return false; } status = -1; @@ -337,20 +335,20 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateChannel"); - status = rpc_write(rpch, s_p4->data, s_p4->size, 4); + status = rpc_write(rpc, s_p4->data, s_p4->size, 4); if (status <= 0) { - printf("rpch_write opnum=4 failed!\n"); + printf("rpc_write opnum=4 failed!\n"); return false; } xfree(dest_addr_unic); - status = rpc_read(rpch, data, length); + status = rpc_read(rpc, data, length); if (status < 0) { - printf("rpch_recv failed!\n"); + printf("rpc_recv failed!\n"); return false; } @@ -374,51 +372,53 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxySetupReceivePipe"); - status = rpc_write(rpch, tsg_packet5, sizeof(tsg_packet5), 8); + status = rpc_write(rpc, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) { - printf("rpch_write opnum=8 failed!\n"); + printf("rpc_write opnum=8 failed!\n"); return false; } return true; } +uint8 pp[8] = +{ + 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) { + STREAM* s; + uint8* tsg_pkg; int status = -1; uint16 opnum = 9; uint32 tsg_length = length + 16 + 4 + 12 + 8; uint32 totalDataBytes = length + 4; - STREAM* s = stream_new(12); - stream_write_uint32_be(s,totalDataBytes); - stream_write_uint32_be(s,0x01); - stream_write_uint32_be(s,length); + s = stream_new(12); + stream_write_uint32_be(s, totalDataBytes); + stream_write_uint32_be(s, 0x01); + stream_write_uint32_be(s, length); - uint8* tsg_pkg = xmalloc(tsg_length); + tsg_pkg = xmalloc(tsg_length); memset(tsg_pkg, 0, 4); memcpy(tsg_pkg + 4, tsg->channelContext, 16); memcpy(tsg_pkg + 20, s->data, 12); memcpy(tsg_pkg + 32, data, length); - uint8 pp[8] = - { - 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - memcpy(tsg_pkg + 32 + length, pp, 8); - status = rpc_write(tsg->rpch, tsg_pkg, tsg_length, opnum); + status = rpc_write(tsg->rpc, tsg_pkg, tsg_length, opnum); xfree(tsg_pkg); stream_free(s); if (status <= 0) { - printf("rpch_write failed!\n"); + printf("rpc_write failed!\n"); return -1; } @@ -429,7 +429,7 @@ int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) { int status; - status = rpc_read(tsg->rpch, data, length); + status = rpc_read(tsg->rpc, data, length); return status; } @@ -440,7 +440,7 @@ rdpTsg* tsg_new(rdpSettings* settings) tsg = (rdpTsg*) xzalloc(sizeof(rdpTsg)); tsg->settings = settings; - tsg->rpch = rpc_new(settings); + tsg->rpc = rpc_new(settings); return tsg; } diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 18a477929..76b9f9512 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -36,7 +36,7 @@ typedef struct rdp_tsg rdpTsg; struct rdp_tsg { - rdpRpc* rpch; + rdpRpc* rpc; uint8* tunnelContext; uint8* channelContext; rdpSettings* settings; diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp-crypto/crypto.c index 12a1d6c53..3b38a0c28 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp-crypto/crypto.c @@ -548,7 +548,7 @@ char* crypto_encode_base64(uint8* data, int length) base64_string = xmalloc(bptr->length); memcpy(base64_string, bptr->data, bptr->length - 1); - base64_string[bptr->length] = '\0'; + base64_string[bptr->length - 1] = '\0'; BIO_free_all(b64); From e73a9c83a726486b797b34050fb4a20e8fd843bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Apr 2012 13:40:57 -0400 Subject: [PATCH 16/47] libfreerdp-core: fix first RTS packets sent --- libfreerdp-core/rpc.c | 183 +++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 102 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index a63e1f0f6..9ff066c9b 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -128,14 +128,6 @@ boolean ntlm_authenticate(rdpNtlm* ntlm) 0, &ntlm->context, &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration); -#ifdef WITH_DEBUG_RPC - if (ntlm->haveInputBuffer) - { - printf("NTLM Token (%d)\n", ntlm->inputBuffer.cbBuffer); - freerdp_hexdump(ntlm->inputBuffer.pvBuffer, ntlm->inputBuffer.cbBuffer); - } -#endif - if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) { if (ntlm->table->CompleteAuthToken != NULL) @@ -192,11 +184,6 @@ STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, ui HttpContext* http_context; HttpRequest* http_request; -#ifdef WITH_DEBUG_RPC - printf("NTLM Token (%d):\n", ntlm_token->cbBuffer); - freerdp_hexdump(ntlm_token->pvBuffer, ntlm_token->cbBuffer); -#endif - base64_ntlm_token = crypto_encode_base64(ntlm_token->pvBuffer, ntlm_token->cbBuffer); if (strcmp(command, "RPC_IN_DATA") == 0) @@ -236,7 +223,7 @@ boolean rpc_out_connect_http(rdpRpc* rpc) s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); - DEBUG_RPC("%s", s->data); + DEBUG_RPC("\n%s", s->data); tls_write_all(tls_out, s->data, s->size); http_response = http_response_recv(tls_out); @@ -251,7 +238,7 @@ boolean rpc_out_connect_http(rdpRpc* rpc) s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 76); - DEBUG_RPC("%s", s->data); + DEBUG_RPC("\n%s", s->data); tls_write_all(tls_out, s->data, s->size); /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ @@ -278,7 +265,7 @@ boolean rpc_in_connect_http(rdpRpc* rpc) http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); - DEBUG_RPC("%s", http_stream->data); + DEBUG_RPC("\n%s", http_stream->data); tls_write_all(tls_in, http_stream->data, http_stream->size); http_response = http_response_recv(tls_in); @@ -293,7 +280,7 @@ boolean rpc_in_connect_http(rdpRpc* rpc) http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0x40000000); - DEBUG_RPC("%s", http_stream->data); + DEBUG_RPC("\n%s", http_stream->data); tls_write_all(tls_in, http_stream->data, http_stream->size); /* At this point IN connection is ready to send CONN/B1 and start with sending data */ @@ -359,111 +346,102 @@ uint8* rpc_create_cookie() return ret; } +void rts_pdu_header_write(STREAM* s, uint8 pfc_flags, uint16 frag_length, uint16 auth_length, + uint32 call_id, uint16 flags, uint16 numberOfCommands) +{ + 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) */ +} + +void rts_version_command_write(STREAM* s) +{ + stream_write_uint32(s, 6); /* CommandType (4 bytes) */ + stream_write_uint32(s, 1); /* Version (4 bytes) */ +} + +void rts_cookie_command_write(STREAM* s, uint8* cookie) +{ + stream_write_uint32(s, 3); /* CommandType (4 bytes) */ + stream_write(s, cookie, 16); /* Cookie (16 bytes) */ +} + +void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize) +{ + stream_write_uint32(s, 0); /* CommandType (4 bytes) */ + stream_write_uint32(s, receiveWindowSize); /* ReceiveWindowSize (4 bytes) */ +} + +void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime) +{ + stream_write_uint32(s, 4); /* CommandType (4 bytes) */ + stream_write_uint32(s, channelLifetime); /* ChannelLifetime (4 bytes) */ +} + +void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive) +{ + stream_write_uint32(s, 5); /* CommandType (4 bytes) */ + stream_write_uint32(s, clientKeepalive); /* ClientKeepalive (4 bytes) */ +} + +void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId) +{ + stream_write_uint32(s, 12); /* CommandType (4 bytes) */ + stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */ +} + boolean rpc_out_send_CONN_A1(rdpRpc* rpc) { - STREAM* pdu = stream_new(76); + STREAM* s; + uint32 ReceiveWindowSize; DEBUG_RPC("Sending CONN_A1"); - 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 = 76; - uint16 auth_length = 0; - uint32 call_id = 0x00000000; - uint16 flags = 0x0000; - uint16 num_commands = 0x0004; - uint32 vCommandType = 0x00000006; - uint32 Version = 0x00000001; - uint32 vccCommandType = 0x00000003; - uint32 occCommandType = 0x00000003; - uint32 rwsCommandType = 0x00000000; - uint32 receiveWindowSize = 0x00010000; - + s = stream_new(76); + ReceiveWindowSize = 0x00010000; rpc->virtualConnectionCookie = rpc_create_cookie(); /* 16 bytes */ rpc->OUTChannelCookie = rpc_create_cookie(); /* 16 bytes */ - rpc->AwailableWindow = receiveWindowSize; + rpc->AwailableWindow = ReceiveWindowSize; - stream_write_uint8(pdu, rpc_vers); - stream_write_uint8(pdu, rpc_vers_minor); - stream_write_uint8(pdu, ptype); - stream_write_uint8(pdu, pfc_flags); - stream_write_uint32(pdu, packet_drep); - stream_write_uint16(pdu, frag_length); - stream_write_uint16(pdu, auth_length); - stream_write_uint32(pdu, call_id); - stream_write_uint16(pdu, flags); - stream_write_uint16(pdu, num_commands); - stream_write_uint32(pdu, vCommandType); - stream_write_uint32(pdu, Version); - stream_write_uint32(pdu, vccCommandType); - stream_write(pdu, rpc->virtualConnectionCookie, 16); - stream_write_uint32(pdu, occCommandType); - stream_write(pdu, rpc->OUTChannelCookie, 16); - stream_write_uint32(pdu, rwsCommandType); - stream_write_uint32(pdu, receiveWindowSize); + rts_pdu_header_write(s, PFC_FIRST_FRAG | PFC_LAST_FRAG, 76, 0, 0, 0, 4); /* 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, pdu->data, stream_get_length(pdu)); + rpc_out_write(rpc, s->data, stream_get_length(s)); - stream_free(pdu); + stream_free(s); return true; } boolean rpc_in_send_CONN_B1(rdpRpc* rpc) { - STREAM* s = stream_new(104); + STREAM* s; + uint8* AssociationGroupId; DEBUG_RPC("Sending CONN_B1"); - 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 = 104; - uint16 auth_length = 0; - uint32 call_id = 0x00000000; - uint16 flags = 0x0000; - uint16 num_commands = 0x0006; - uint32 vCommandType = 0x00000006; - uint32 Version = 0x00000001; - uint32 vccCommandType = 0x00000003; - uint32 iccCommandType = 0x00000003; - uint32 clCommandType = 0x00000004; - uint32 ChannelLifetime = 0x40000000; - uint32 ckCommandType = 0x00000005; - uint32 ClientKeepalive = 0x000493e0; - uint32 agidCommandType = 0x0000000c; - uint8* AssociationGroupId; - + s = stream_new(104); rpc->INChannelCookie = rpc_create_cookie(); /* 16 bytes */ AssociationGroupId = rpc_create_cookie(); /* 16 bytes */ - 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, vCommandType); - stream_write_uint32(s, Version); - stream_write_uint32(s, vccCommandType); - stream_write(s, rpc->virtualConnectionCookie, 16); - stream_write_uint32(s, iccCommandType); - stream_write(s, rpc->INChannelCookie, 16); - stream_write_uint32(s, clCommandType); - stream_write_uint32(s, ChannelLifetime); - stream_write_uint32(s, ckCommandType); - stream_write_uint32(s, ClientKeepalive); - stream_write_uint32(s, agidCommandType); - stream_write(s, AssociationGroupId, 16); + rts_pdu_header_write(s, PFC_FIRST_FRAG | PFC_LAST_FRAG, 104, 0, 0, 0, 6); /* 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) */ + rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ + rts_client_keepalive_command_write(s, 0x000493e0); /* ClientKeepalive (8 bytes) */ + rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ stream_seal(s); rpc_in_write(rpc, s->data, s->size); @@ -925,7 +903,7 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) if (strncmp((char*) pdu, "HTTP", 4) == 0) { - printf("Unexpected HTTP response, likely caused by an NTLM HTTP authentication failure\n"); + printf("\n%s", (char*) pdu); return -1; } @@ -1217,7 +1195,8 @@ rdpRpc* rpc_new(rdpSettings* settings) http_context_set_user_agent(rpc->http_out->context, "MSRPC"); http_context_set_host(rpc->http_out->context, settings->tsg_hostname); http_context_set_pragma(rpc->http_out->context, - "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729" ", " + "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624"); rpc->read_buffer = NULL; rpc->write_buffer = NULL; From de14b532a6a157c9c6bdc617bf2a8d0d30938b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Apr 2012 14:09:27 -0400 Subject: [PATCH 17/47] libfreerdp-core: start rts.c --- libfreerdp-core/CMakeLists.txt | 2 + libfreerdp-core/rpc.c | 53 +------------------- libfreerdp-core/rpc.h | 48 +----------------- libfreerdp-core/rts.c | 71 ++++++++++++++++++++++++++ libfreerdp-core/rts.h | 92 ++++++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+), 99 deletions(-) create mode 100644 libfreerdp-core/rts.c create mode 100644 libfreerdp-core/rts.h diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index ca19a0aee..d30b53f3f 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -39,6 +39,8 @@ set(LIBFREERDP_CORE_SRCS http.h rpc.c rpc.h + rts.c + rts.h input.c input.h license.c diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 9ff066c9b..42b070989 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -346,57 +346,6 @@ uint8* rpc_create_cookie() return ret; } -void rts_pdu_header_write(STREAM* s, uint8 pfc_flags, uint16 frag_length, uint16 auth_length, - uint32 call_id, uint16 flags, uint16 numberOfCommands) -{ - 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) */ -} - -void rts_version_command_write(STREAM* s) -{ - stream_write_uint32(s, 6); /* CommandType (4 bytes) */ - stream_write_uint32(s, 1); /* Version (4 bytes) */ -} - -void rts_cookie_command_write(STREAM* s, uint8* cookie) -{ - stream_write_uint32(s, 3); /* CommandType (4 bytes) */ - stream_write(s, cookie, 16); /* Cookie (16 bytes) */ -} - -void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize) -{ - stream_write_uint32(s, 0); /* CommandType (4 bytes) */ - stream_write_uint32(s, receiveWindowSize); /* ReceiveWindowSize (4 bytes) */ -} - -void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime) -{ - stream_write_uint32(s, 4); /* CommandType (4 bytes) */ - stream_write_uint32(s, channelLifetime); /* ChannelLifetime (4 bytes) */ -} - -void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive) -{ - stream_write_uint32(s, 5); /* CommandType (4 bytes) */ - stream_write_uint32(s, clientKeepalive); /* ClientKeepalive (4 bytes) */ -} - -void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId) -{ - stream_write_uint32(s, 12); /* CommandType (4 bytes) */ - stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */ -} - boolean rpc_out_send_CONN_A1(rdpRpc* rpc) { STREAM* s; @@ -501,7 +450,7 @@ boolean rpc_in_send_bind(rdpRpc* rpc) DEBUG_RPC("TODO: complete NTLM integration"); - ntlm_client_init(rpc->ntlm, settings->username, settings->password, settings->domain); + ntlm_client_init(rpc->ntlm, settings->username, settings->domain, settings->password); ntlm_authenticate(rpc->ntlm); ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index e55fa15f7..8d8453a99 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -25,6 +25,7 @@ typedef struct rdp_rpc rdpRpc; typedef struct rdp_rpc_http rdpRpcHTTP; #include "tcp.h" +#include "rts.h" #include "http.h" #include @@ -40,53 +41,6 @@ typedef struct rdp_rpc_http rdpRpcHTTP; #include #include -#define PTYPE_REQUEST 0x00 -#define PTYPE_PING 0x01 -#define PTYPE_RESPONSE 0x02 -#define PTYPE_FAULT 0x03 -#define PTYPE_WORKING 0x04 -#define PTYPE_NOCALL 0x05 -#define PTYPE_REJECT 0x06 -#define PTYPE_ACK 0x07 -#define PTYPE_CL_CANCEL 0x08 -#define PTYPE_FACK 0x09 -#define PTYPE_CANCEL_ACK 0x0a -#define PTYPE_BIND 0x0b -#define PTYPE_BIND_ACK 0x0c -#define PTYPE_BIND_NAK 0x0d -#define PTYPE_ALTER_CONTEXT 0x0e -#define PTYPE_ALTER_CONTEXT_RESP 0x0f -#define PTYPE_RPC_AUTH_3 0x10 -#define PTYPE_SHUTDOWN 0x11 -#define PTYPE_CO_CANCEL 0x12 -#define PTYPE_ORPHANED 0x13 -#define PTYPE_RTS 0x14 - -#define PFC_FIRST_FRAG 0x01/* First fragment */ -#define PFC_LAST_FRAG 0x02/* Last fragment */ -#define PFC_PENDING_CANCEL 0x04/* Cancel was pending at sender */ -#define PFC_RESERVED_1 0x08 -#define PFC_CONC_MPX 0x10/* supports concurrent multiplexing - * of a single connection. */ -#define PFC_DID_NOT_EXECUTE 0x20/* only meaningful on `fault' packet; - * if true, guaranteed call did not - * execute. */ -#define PFC_MAYBE 0x40/* `maybe' call semantics requested */ -#define PFC_OBJECT_UUID 0x80/* if true, a non-nil object UUID - * was specified in the handle, and - * is present in the optional object - * field. If false, the object field - * is omitted. */ - -#define RTS_FLAG_NONE 0x0000 /*No special flags.*/ -#define RTS_FLAG_PING 0x0001 /*Proves that the sender is still active; can also be used to flush the pipeline by the other party.*/ -#define RTS_FLAG_OTHER_CMD 0x0002 /*Indicates that the PDU contains a command that cannot be defined by the other flags in this table.*/ -#define RTS_FLAG_RECYCLE_CHANNEL 0x0004 /*Indicates that the PDU is associated with recycling a channel.*/ -#define RTS_FLAG_IN_CHANNEL 0x0008 /*Indicates that the PDU is associated with IN channel communications.*/ -#define RTS_FLAG_OUT_CHANNEL 0x0010 /*Indicates that the PDU is associated with OUT channel communications.*/ -#define RTS_FLAG_EOF 0x0020 /*Indicates that this is the last PDU on an IN channel or OUT channel. Not all channels, however, use this to indicate the last PDU.*/ -#define RTS_FLAG_ECHO 0x0040 /*Signifies that this PDU is an echo request or response.*/ - typedef uint16 p_context_id_t; typedef struct { diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c new file mode 100644 index 000000000..dc62b2b10 --- /dev/null +++ b/libfreerdp-core/rts.c @@ -0,0 +1,71 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Request To Send (RTS) PDUs + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#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) +{ + 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) */ +} + +void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize) +{ + stream_write_uint32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */ + stream_write_uint32(s, receiveWindowSize); /* ReceiveWindowSize (4 bytes) */ +} + +void rts_cookie_command_write(STREAM* s, uint8* cookie) +{ + stream_write_uint32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */ + stream_write(s, cookie, 16); /* Cookie (16 bytes) */ +} + +void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime) +{ + stream_write_uint32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */ + stream_write_uint32(s, channelLifetime); /* ChannelLifetime (4 bytes) */ +} + +void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive) +{ + stream_write_uint32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */ + stream_write_uint32(s, clientKeepalive); /* ClientKeepalive (4 bytes) */ +} + +void rts_version_command_write(STREAM* s) +{ + stream_write_uint32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */ + stream_write_uint32(s, 1); /* Version (4 bytes) */ +} + +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) */ +} diff --git a/libfreerdp-core/rts.h b/libfreerdp-core/rts.h new file mode 100644 index 000000000..9ce8cfb92 --- /dev/null +++ b/libfreerdp-core/rts.h @@ -0,0 +1,92 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Request To Send (RTS) PDUs + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CORE_RTS_H +#define FREERDP_CORE_RTS_H + +#include +#include + +#define PTYPE_REQUEST 0x00 +#define PTYPE_PING 0x01 +#define PTYPE_RESPONSE 0x02 +#define PTYPE_FAULT 0x03 +#define PTYPE_WORKING 0x04 +#define PTYPE_NOCALL 0x05 +#define PTYPE_REJECT 0x06 +#define PTYPE_ACK 0x07 +#define PTYPE_CL_CANCEL 0x08 +#define PTYPE_FACK 0x09 +#define PTYPE_CANCEL_ACK 0x0A +#define PTYPE_BIND 0x0B +#define PTYPE_BIND_ACK 0x0C +#define PTYPE_BIND_NAK 0x0D +#define PTYPE_ALTER_CONTEXT 0x0E +#define PTYPE_ALTER_CONTEXT_RESP 0x0F +#define PTYPE_RPC_AUTH_3 0x10 +#define PTYPE_SHUTDOWN 0x11 +#define PTYPE_CO_CANCEL 0x12 +#define PTYPE_ORPHANED 0x13 +#define PTYPE_RTS 0x14 + +#define PFC_FIRST_FRAG 0x01 +#define PFC_LAST_FRAG 0x02 +#define PFC_PENDING_CANCEL 0x04 +#define PFC_RESERVED_1 0x08 +#define PFC_CONC_MPX 0x10 +#define PFC_DID_NOT_EXECUTE 0x20 +#define PFC_MAYBE 0x40 +#define PFC_OBJECT_UUID 0x80 + +#define RTS_FLAG_NONE 0x0000 +#define RTS_FLAG_PING 0x0001 +#define RTS_FLAG_OTHER_CMD 0x0002 +#define RTS_FLAG_RECYCLE_CHANNEL 0x0004 +#define RTS_FLAG_IN_CHANNEL 0x0008 +#define RTS_FLAG_OUT_CHANNEL 0x0010 +#define RTS_FLAG_EOF 0x0020 +#define RTS_FLAG_ECHO 0x0040 + +#define RTS_CMD_RECEIVE_WINDOW_SIZE 0x00000000 +#define RTS_CMD_FLOW_CONTROL_ACK 0x00000001 +#define RTS_CMD_CONNECTION_TIMEOUT 0x00000002 +#define RTS_CMD_COOKIE 0x00000003 +#define RTS_CMD_CHANNEL_LIFETIME 0x00000004 +#define RTS_CMD_CLIENT_KEEPALIVE 0x00000005 +#define RTS_CMD_VERSION 0x00000006 +#define RTS_CMD_EMPTY 0x00000007 +#define RTS_CMD_PADDING 0x00000008 +#define RTS_CMD_NEGATIVE_ANCE 0x00000009 +#define RTS_CMD_ANCE 0x0000000A +#define RTS_CMD_CLIENT_ADDRESS 0x0000000B +#define RTS_CMD_ASSOCIATION_GROUP_ID 0x0000000C +#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); + +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_association_group_id_command_write(STREAM* s, uint8* associationGroupId); + +#endif /* FREERDP_CORE_RTS_H */ From 97391dc78248dfa29450cbf661964f7a682c829e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Apr 2012 15:43:20 -0400 Subject: [PATCH 18/47] libfreerdp-core: cleanup RTS header encoding --- include/freerdp/crypto/crypto.h | 3 +- libfreerdp-core/rpc.c | 181 +++++++++++--------------------- libfreerdp-core/rpc.h | 2 + libfreerdp-core/rts.c | 149 +++++++++++++++++++++++--- libfreerdp-core/rts.h | 24 ++++- libfreerdp-crypto/crypto.c | 27 +---- 6 files changed, 227 insertions(+), 159 deletions(-) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index 5cbd074be..d3c3d74ae 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -142,8 +142,7 @@ FREERDP_API void crypto_rsa_private_decrypt(const uint8* input, int length, uint 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 */ diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 42b070989..a6ab3b1b2 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -184,7 +184,7 @@ STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, ui 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; @@ -349,24 +349,39 @@ uint8* rpc_create_cookie() 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); @@ -376,15 +391,30 @@ boolean rpc_out_send_CONN_A1(rdpRpc* rpc) 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) */ @@ -402,35 +432,29 @@ boolean rpc_in_send_CONN_B1(rdpRpc* rpc) boolean rpc_in_send_keep_alive(rdpRpc* rpc) { - STREAM* s = stream_new(28); + STREAM* s; + RTS_PDU_HEADER header; - 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; + 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; - 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); + 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); @@ -709,96 +733,9 @@ int rpc_out_read_http_header(rdpRpc* rpc) 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; @@ -831,7 +768,9 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) 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; } diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 8d8453a99..00307e75a 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -593,6 +593,8 @@ void ntlm_free(rdpNtlm* ntlm); 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); diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index dc62b2b10..1139b1cdd 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -19,19 +19,21 @@ #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) @@ -64,8 +66,131 @@ void rts_version_command_write(STREAM* s) 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; +} diff --git a/libfreerdp-core/rts.h b/libfreerdp-core/rts.h index 9ce8cfb92..f29208a31 100644 --- a/libfreerdp-core/rts.h +++ b/libfreerdp-core/rts.h @@ -20,6 +20,8 @@ #ifndef FREERDP_CORE_RTS_H #define FREERDP_CORE_RTS_H +#include "rpc.h" + #include #include @@ -79,14 +81,32 @@ #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 */ diff --git a/libfreerdp-crypto/crypto.c b/libfreerdp-crypto/crypto.c index 3b38a0c28..93a114e85 100644 --- a/libfreerdp-crypto/crypto.c +++ b/libfreerdp-crypto/crypto.c @@ -511,27 +511,7 @@ void crypto_cert_print_info(X509* xcert) 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; @@ -543,7 +523,10 @@ char* crypto_encode_base64(uint8* data, int length) 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); From 21eea06a752f0728fde4c8198f2c24a18aca1833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 20 Apr 2012 17:00:00 -0400 Subject: [PATCH 19/47] libfreerdp-core: NTLM support for non-sealing usage, RTS improvements --- libfreerdp-core/rpc.c | 123 +++++++------- libfreerdp-core/rpc.h | 3 +- libfreerdp-core/rts.c | 253 +++++++++++++++++++++++----- libfreerdp-core/rts.h | 55 +++++- libfreerdp-sspi/NTLM/ntlm.c | 10 +- libfreerdp-sspi/NTLM/ntlm.h | 1 + libfreerdp-sspi/NTLM/ntlm_message.c | 10 +- 7 files changed, 335 insertions(+), 120 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index a6ab3b1b2..c94d5a556 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -43,13 +43,15 @@ boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, #define NTLM_PACKAGE_NAME _T("NTLM") -boolean ntlm_client_init(rdpNtlm* ntlm, char* user, char* domain, char* password) +boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password) { size_t size; SECURITY_STATUS status; sspi_GlobalInit(); + ntlm->confidentiality = confidentiality; + ntlm->table = InitSecurityInterface(); ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; @@ -96,8 +98,10 @@ boolean ntlm_client_init(rdpNtlm* ntlm, char* user, char* domain, char* password memset(&ntlm->outputBuffer, 0, sizeof(SecBuffer)); memset(&ntlm->ContextSizes, 0, sizeof(SecPkgContext_Sizes)); - ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE; + ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_DELEGATE; + + if (ntlm->confidentiality) + ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY; return true; } @@ -217,7 +221,7 @@ boolean rpc_out_connect_http(rdpRpc* rpc) rdpRpcHTTP* http_out = rpc->http_out; rdpNtlm* http_out_ntlm = http_out->ntlm; - ntlm_client_init(http_out_ntlm, settings->username, settings->domain, settings->password); + ntlm_client_init(http_out_ntlm, true, settings->username, settings->domain, settings->password); ntlm_authenticate(http_out_ntlm); @@ -259,7 +263,7 @@ boolean rpc_in_connect_http(rdpRpc* rpc) rdpRpcHTTP* http_in = rpc->http_in; rdpNtlm* http_in_ntlm = http_in->ntlm; - ntlm_client_init(http_in_ntlm, settings->username, settings->domain, settings->password); + ntlm_client_init(http_in_ntlm, true, settings->username, settings->domain, settings->password); ntlm_authenticate(http_in_ntlm); @@ -474,7 +478,7 @@ boolean rpc_in_send_bind(rdpRpc* rpc) DEBUG_RPC("TODO: complete NTLM integration"); - ntlm_client_init(rpc->ntlm, settings->username, settings->domain, settings->password); + ntlm_client_init(rpc->ntlm, false, settings->username, settings->domain, settings->password); ntlm_authenticate(rpc->ntlm); ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; @@ -580,8 +584,9 @@ boolean rpc_in_send_bind(rdpRpc* rpc) stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); + stream_seal(pdu); - rpc_in_write(rpc, pdu->data, stream_get_length(pdu)); + rpc_in_write(rpc, pdu->data, pdu->size); /* TODO there is some allocated memory */ xfree(bind_pdu); @@ -643,46 +648,35 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) boolean rpc_in_send_flow_control(rdpRpc* rpc) { - STREAM* s = stream_new(56); + STREAM* s; + RTS_PDU_HEADER header; - uint8* b; - 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 = 56; - uint16 auth_length = 0; - uint32 call_id = 0x00000000; - uint16 flags = 0x0002; - uint16 num_commands = 0x0002; - uint32 ckCommandType = 0x0000000d; - uint32 ClientKeepalive = 0x00000003; - uint32 a = 0x00000001; - uint32 aa = rpc->BytesReceived; - uint32 aaa = 0x00010000; + 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 = 56; + header.auth_length = 0; + header.call_id = 0; + header.flags = 2; + header.numberOfCommands = 2; - rpc->AwailableWindow = aaa; - b = rpc->OUTChannelCookie; + rpc->AwailableWindow = 0x00010000; - 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_write_uint32(s, a); - stream_write_uint32(s, aa); - stream_write_uint32(s, aaa); - stream_write(s, b, 16); + s = stream_new(header.frag_length); + rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ + rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ - rpc_in_write(rpc, s->data, stream_get_length(s)); + /* FlowControlAck Command (28 bytes) */ + rts_flow_control_ack_command_write(s, rpc->BytesReceived, rpc->AwailableWindow, rpc->OUTChannelCookie); + + stream_seal(s); + + rpc_in_write(rpc, s->data, s->size); stream_free(s); @@ -691,31 +685,28 @@ boolean rpc_in_send_flow_control(rdpRpc* rpc) boolean rpc_in_send_ping(rdpRpc* rpc) { - STREAM* s = stream_new(20); + STREAM* s; + RTS_PDU_HEADER header; - 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 = 56; - uint16 auth_length = 0; - uint32 call_id = 0x00000000; - uint16 flags = 0x0001; - uint16 num_commands = 0x0000; + 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 = 20; + header.auth_length = 0; + header.call_id = 0; + header.flags = 1; + header.numberOfCommands = 0; - 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); + s = stream_new(header.frag_length); + rts_pdu_header_write(s, &header); /* RTS Header (20 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); @@ -766,7 +757,7 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) return status; } - if (ptype == 0x14) /* RTS PDU */ + if (ptype == PTYPE_RTS) /* RTS PDU */ { s = stream_new(0); stream_attach(s, pdu, frag_length); diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 00307e75a..4c2f88f09 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -530,6 +530,7 @@ struct rdp_ntlm SecBufferDesc inputBufferDesc; SecBufferDesc outputBufferDesc; CredHandle credentials; + boolean confidentiality; SecPkgInfo* pPackageInfo; SecurityFunctionTable* table; SEC_WINNT_AUTH_IDENTITY identity; @@ -584,7 +585,7 @@ struct rdp_rpc boolean ntlm_authenticate(rdpNtlm* ntlm); -boolean ntlm_client_init(rdpNtlm* ntlm, char* user, char* domain, char* password); +boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password); void ntlm_client_uninit(rdpNtlm* ntlm); rdpNtlm* ntlm_new(); diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index 1139b1cdd..b948e9626 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -19,6 +19,46 @@ #include "rts.h" +#ifdef WITH_DEBUG_RTS + +static const char* const RTS_CMD_STRINGS[] = +{ + "ReceiveWindowSize", + "FlowControlAck", + "ConnectionTimeout", + "Cookie", + "ChannelLifetime", + "ClientKeepalive", + "Version", + "Empty", + "Padding", + "NegativeANCE", + "ANCE", + "ClientAddress", + "AssociationGroupId", + "Destination", + "PingTrafficSentNotify" +}; + +#endif + +void rts_pdu_header_read(STREAM* s, RTS_PDU_HEADER* header) +{ + stream_read_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */ + stream_read_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */ + stream_read_uint8(s, header->ptype); /* PTYPE (1 byte) */ + stream_read_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */ + stream_read_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */ + stream_read_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */ + stream_read_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */ + stream_read_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */ + stream_read_uint16(s, header->frag_length); /* frag_length (2 bytes) */ + stream_read_uint16(s, header->auth_length); /* auth_length (2 bytes) */ + stream_read_uint32(s, header->call_id); /* call_id (4 bytes) */ + stream_read_uint16(s, header->flags); /* flags (2 bytes) */ + stream_read_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */ +} + void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header) { stream_write_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */ @@ -36,28 +76,82 @@ void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header) stream_write_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */ } -void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize) +void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* ReceiveWindowSize (4 bytes) */ +} + +void rts_receive_window_size_command_write(STREAM* s, uint32 ReceiveWindowSize) { stream_write_uint32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */ - stream_write_uint32(s, receiveWindowSize); /* ReceiveWindowSize (4 bytes) */ + stream_write_uint32(s, ReceiveWindowSize); /* ReceiveWindowSize (4 bytes) */ } -void rts_cookie_command_write(STREAM* s, uint8* cookie) +void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s) +{ + /* Ack (24 bytes) */ + stream_seek_uint32(s); /* BytesReceived (4 bytes) */ + stream_seek_uint32(s); /* AvailableWindow (4 bytes) */ + stream_seek(s, 16); /* ChannelCookie (16 bytes) */ +} + +void rts_flow_control_ack_command_write(STREAM* s, uint32 BytesReceived, uint32 AvailableWindow, uint8* ChannelCookie) +{ + stream_write_uint32(s, RTS_CMD_FLOW_CONTROL_ACK); /* CommandType (4 bytes) */ + + /* Ack (24 bytes) */ + stream_write_uint32(s, BytesReceived); /* BytesReceived (4 bytes) */ + stream_write_uint32(s, AvailableWindow); /* AvailableWindow (4 bytes) */ + stream_write(s, ChannelCookie, 16); /* ChannelCookie (16 bytes) */ +} + +void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* ConnectionTimeout (4 bytes) */ +} + +void rts_connection_timeout_command_write(STREAM* s, uint32 ConnectionTimeout) +{ + stream_write_uint32(s, RTS_CMD_CONNECTION_TIMEOUT); /* CommandType (4 bytes) */ + stream_write_uint32(s, ConnectionTimeout); /* ConnectionTimeout (4 bytes) */ +} + +void rts_cookie_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek(s, 16); /* Cookie (16 bytes) */ +} + +void rts_cookie_command_write(STREAM* s, uint8* Cookie) { stream_write_uint32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */ - stream_write(s, cookie, 16); /* Cookie (16 bytes) */ + stream_write(s, Cookie, 16); /* Cookie (16 bytes) */ } -void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime) +void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* ChannelLifetime (4 bytes) */ +} + +void rts_channel_lifetime_command_write(STREAM* s, uint32 ChannelLifetime) { stream_write_uint32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */ - stream_write_uint32(s, channelLifetime); /* ChannelLifetime (4 bytes) */ + stream_write_uint32(s, ChannelLifetime); /* ChannelLifetime (4 bytes) */ } -void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive) +void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* ClientKeepalive (4 bytes) */ +} + +void rts_client_keepalive_command_write(STREAM* s, uint32 ClientKeepalive) { stream_write_uint32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */ - stream_write_uint32(s, clientKeepalive); /* ClientKeepalive (4 bytes) */ + stream_write_uint32(s, ClientKeepalive); /* ClientKeepalive (4 bytes) */ +} + +void rts_version_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* Version (4 bytes) */ } void rts_version_command_write(STREAM* s) @@ -66,7 +160,17 @@ void rts_version_command_write(STREAM* s) stream_write_uint32(s, 1); /* Version (4 bytes) */ } -void rts_padding_command_read(STREAM* s) +void rts_empty_command_read(rdpRpc* rpc, STREAM* s) +{ + +} + +void rts_empty_command_write(STREAM* s) +{ + stream_write_uint32(s, RTS_CMD_EMPTY); /* CommandType (4 bytes) */ +} + +void rts_padding_command_read(rdpRpc* rpc, STREAM* s) { uint32 ConformanceCount; @@ -74,17 +178,37 @@ void rts_padding_command_read(STREAM* s) stream_seek(s, ConformanceCount); /* Padding (variable) */ } -void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId) +void rts_padding_command_write(STREAM* s, uint32 ConformanceCount) { - stream_write_uint32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */ - stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */ + stream_write_uint32(s, ConformanceCount); /* ConformanceCount (4 bytes) */ + stream_write_zero(s, ConformanceCount); /* Padding (variable) */ } -void rts_client_address_command_read(STREAM* s) +void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s) +{ + +} + +void rts_negative_ance_command_write(STREAM* s) +{ + stream_write_uint32(s, RTS_CMD_NEGATIVE_ANCE); /* CommandType (4 bytes) */ +} + +void rts_ance_command_read(rdpRpc* rpc, STREAM* s) +{ + +} + +void rts_ance_command_write(STREAM* s) +{ + stream_write_uint32(s, RTS_CMD_ANCE); /* CommandType (4 bytes) */ +} + +void rts_client_address_command_read(rdpRpc* rpc, STREAM* s) { uint32 AddressType; - stream_read_uint32(s, AddressType); /* ConformanceCount (4 bytes) */ + stream_read_uint32(s, AddressType); /* AddressType (4 bytes) */ if (AddressType == 0) { @@ -98,95 +222,142 @@ void rts_client_address_command_read(STREAM* s) stream_seek(s, 12); /* padding (12 bytes) */ } +void rts_client_address_command_write(STREAM* s, uint32 AddressType, uint8* ClientAddress) +{ + stream_write_uint32(s, RTS_CMD_CLIENT_ADDRESS); /* CommandType (4 bytes) */ + stream_write_uint32(s, AddressType); /* AddressType (4 bytes) */ + + if (AddressType == 0) + { + stream_write(s, ClientAddress, 4); /* ClientAddress (4 bytes) */ + } + else + { + stream_write(s, ClientAddress, 16); /* ClientAddress (16 bytes) */ + } + + stream_write_zero(s, 12); /* padding (12 bytes) */ +} + +void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek(s, 16); /* AssociationGroupId (16 bytes) */ +} + +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_destination_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* Destination (4 bytes) */ +} + +void rts_destination_command_write(STREAM* s, uint32 Destination) +{ + stream_write_uint32(s, RTS_CMD_DESTINATION); /* CommandType (4 bytes) */ + stream_write_uint32(s, Destination); /* Destination (4 bytes) */ +} + +void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s) +{ + stream_seek_uint32(s); /* PingTrafficSent (4 bytes) */ +} + +void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSent) +{ + stream_write_uint32(s, RTS_CMD_PING_TRAFFIC_SENT_NOTIFY); /* CommandType (4 bytes) */ + stream_write_uint32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */ +} + int rts_pdu_recv(rdpRpc* rpc, STREAM* s) { int i; - uint16 flags; uint32 CommandType; - uint16 numberOfCommands; + RTS_PDU_HEADER header; - 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) */ + rts_pdu_header_read(s, &header); - if (flags & RTS_FLAG_PING) + DEBUG_RTS("numberOfCommands:%d", header.numberOfCommands); + + if (header.flags & RTS_FLAG_PING) { rpc_in_send_keep_alive(rpc); return 0; } - for (i = 0; i < numberOfCommands; i++) + for (i = 0; i < header.numberOfCommands; i++) { stream_read_uint32(s, CommandType); /* CommandType (4 bytes) */ + DEBUG_RTS("CommandType: %s (0x%08X)", RTS_CMD_STRINGS[CommandType % 14], CommandType); + switch (CommandType) { case RTS_CMD_RECEIVE_WINDOW_SIZE: - stream_seek(s, 4); + rts_receive_window_size_command_read(rpc, s); break; case RTS_CMD_FLOW_CONTROL_ACK: - stream_seek(s, 24); + rts_flow_control_ack_command_read(rpc, s); break; case RTS_CMD_CONNECTION_TIMEOUT: - stream_seek(s, 4); + rts_connection_timeout_command_read(rpc, s); break; case RTS_CMD_COOKIE: - stream_seek(s, 16); + rts_cookie_command_read(rpc, s); break; case RTS_CMD_CHANNEL_LIFETIME: - stream_seek(s, 4); + rts_channel_lifetime_command_read(rpc, s); break; case RTS_CMD_CLIENT_KEEPALIVE: - stream_seek(s, 4); + rts_client_keepalive_command_read(rpc, s); break; case RTS_CMD_VERSION: - stream_seek(s, 4); + rts_version_command_read(rpc, s); break; case RTS_CMD_EMPTY: + rts_empty_command_read(rpc, s); break; case RTS_CMD_PADDING: - rts_padding_command_read(s); + rts_padding_command_read(rpc, s); break; case RTS_CMD_NEGATIVE_ANCE: + rts_negative_ance_command_read(rpc, s); break; case RTS_CMD_ANCE: + rts_ance_command_read(rpc, s); break; case RTS_CMD_CLIENT_ADDRESS: - rts_client_address_command_read(s); + rts_client_address_command_read(rpc, s); break; case RTS_CMD_ASSOCIATION_GROUP_ID: - stream_seek(s, 16); + rts_association_group_id_command_read(rpc, s); break; case RTS_CMD_DESTINATION: - stream_seek(s, 4); + rts_destination_command_read(rpc, s); break; case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY: - stream_seek(s, 4); + rts_ping_traffic_sent_notify_command_read(rpc, s); break; default: - printf(" Error: Unknown RTS Command Type: 0x%x\n", CommandType); + printf("Error: Unknown RTS Command Type: 0x%x\n", CommandType); return -1; break; } diff --git a/libfreerdp-core/rts.h b/libfreerdp-core/rts.h index f29208a31..ecd24344b 100644 --- a/libfreerdp-core/rts.h +++ b/libfreerdp-core/rts.h @@ -22,7 +22,10 @@ #include "rpc.h" +#include "config.h" + #include +#include #include #define PTYPE_REQUEST 0x00 @@ -81,6 +84,11 @@ #define RTS_CMD_DESTINATION 0x0000000D #define RTS_CMD_PING_TRAFFIC_SENT_NOTIFY 0x0000000E +#define FDClient 0x00000000 +#define FDInProxy 0x00000001 +#define FDServer 0x00000002 +#define FDOutProxy 0x00000003 + struct _rts_pdu_header { uint8 rpc_vers; @@ -96,17 +104,50 @@ struct _rts_pdu_header }; typedef struct _rts_pdu_header RTS_PDU_HEADER; +void rts_pdu_header_read(STREAM* s, RTS_PDU_HEADER* 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_receive_window_size_command_read(rdpRpc* rpc, STREAM* s); +void rts_receive_window_size_command_write(STREAM* s, uint32 ReceiveWindowSize); +void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s); +void rts_flow_control_ack_command_write(STREAM* s, uint32 BytesReceived, uint32 AvailableWindow, uint8* ChannelCookie); +void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s); +void rts_connection_timeout_command_write(STREAM* s, uint32 ConnectionTimeout); +void rts_cookie_command_read(rdpRpc* rpc, STREAM* s); +void rts_cookie_command_write(STREAM* s, uint8* Cookie); +void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s); +void rts_channel_lifetime_command_write(STREAM* s, uint32 ChannelLifetime); +void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s); +void rts_client_keepalive_command_write(STREAM* s, uint32 ClientKeepalive); +void rts_version_command_read(rdpRpc* rpc, STREAM* s); 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); +void rts_empty_command_read(rdpRpc* rpc, STREAM* s); +void rts_empty_command_write(STREAM* s); +void rts_padding_command_read(rdpRpc* rpc, STREAM* s); +void rts_padding_command_write(STREAM* s, uint32 ConformanceCount); +void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s); +void rts_negative_ance_command_write(STREAM* s); +void rts_ance_command_read(rdpRpc* rpc, STREAM* s); +void rts_ance_command_write(STREAM* s); +void rts_client_address_command_read(rdpRpc* rpc, STREAM* s); +void rts_client_address_command_write(STREAM* s, uint32 AddressType, uint8* ClientAddress); +void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s); +void rts_association_group_id_command_write(STREAM* s, uint8* AssociationGroupId); +void rts_destination_command_read(rdpRpc* rpc, STREAM* s); +void rts_destination_command_write(STREAM* s, uint32 Destination); +void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s); +void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSent); int rts_pdu_recv(rdpRpc* rpc, STREAM* s); +#ifdef WITH_DEBUG_TSG +#define WITH_DEBUG_RTS +#endif + +#ifdef WITH_DEBUG_RTS +#define DEBUG_RTS(fmt, ...) DEBUG_CLASS(RTS, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RTS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + #endif /* FREERDP_CORE_RTS_H */ diff --git a/libfreerdp-sspi/NTLM/ntlm.c b/libfreerdp-sspi/NTLM/ntlm.c index 08c684aed..b2b99586c 100644 --- a/libfreerdp-sspi/NTLM/ntlm.c +++ b/libfreerdp-sspi/NTLM/ntlm.c @@ -390,6 +390,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti { context = ntlm_ContextNew(); + if (fContextReq & ISC_REQ_CONFIDENTIALITY) + context->confidentiality = true; + credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); ntlm_SetContextIdentity(context, &credentials->identity); @@ -565,7 +568,12 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, uint32 fQOP HMAC_CTX_cleanup(&hmac); /* Encrypt message using with RC4, result overwrites original buffer */ - crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer); + + if (context->confidentiality) + crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer); + else + memcpy(data_buffer->pvBuffer, data, length); + xfree(data); #ifdef WITH_DEBUG_NTLM diff --git a/libfreerdp-sspi/NTLM/ntlm.h b/libfreerdp-sspi/NTLM/ntlm.h index c960c00ca..08e724373 100644 --- a/libfreerdp-sspi/NTLM/ntlm.h +++ b/libfreerdp-sspi/NTLM/ntlm.h @@ -83,6 +83,7 @@ struct _NTLM_CONTEXT UNICONV* uniconv; int SendSeqNum; int RecvSeqNum; + boolean confidentiality; CryptoRc4 SendRc4Seal; CryptoRc4 RecvRc4Seal; uint8* SendSigningKey; diff --git a/libfreerdp-sspi/NTLM/ntlm_message.c b/libfreerdp-sspi/NTLM/ntlm_message.c index b00be61fb..c6824d8a9 100644 --- a/libfreerdp-sspi/NTLM/ntlm_message.c +++ b/libfreerdp-sspi/NTLM/ntlm_message.c @@ -241,7 +241,6 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; NegotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY; - NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; NegotiateFlags |= NTLMSSP_REQUEST_TARGET; NegotiateFlags |= NTLMSSP_NEGOTIATE_OEM; @@ -254,12 +253,14 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; - NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; NegotiateFlags |= NTLMSSP_REQUEST_TARGET; NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; } + if (context->confidentiality) + NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + context->NegotiateFlags = NegotiateFlags; stream_write_uint32(s, NegotiateFlags); /* NegotiateFlags (4 bytes) */ @@ -964,7 +965,6 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; - NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; NegotiateFlags |= NTLMSSP_REQUEST_TARGET; NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; @@ -976,12 +976,14 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; - NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; NegotiateFlags |= NTLMSSP_REQUEST_TARGET; NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; } + if (context->confidentiality) + NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + if (context->ntlm_v2) PayloadBufferOffset = 80; /* starting buffer offset */ else From 81460cb33d7c8f8b1c5bbf9da6b474917eec72be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 13:28:20 -0400 Subject: [PATCH 20/47] libfreerdp-core: started implementing RTS abstract data model elements --- libfreerdp-core/rpc.c | 120 +++++++++++++++++++++++++++++++----------- libfreerdp-core/rpc.h | 73 ++++++++++++++++++++++--- libfreerdp-core/rts.c | 2 +- 3 files changed, 154 insertions(+), 41 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index c94d5a556..6aef8cca6 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -338,7 +338,7 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length) status = tls_write_all(tls_in, data, length); if (status > 0) - rpc->BytesSent += status; + rpc->VirtualConnection->DefaultInChannel->BytesSent += status; return status; } @@ -350,11 +350,18 @@ uint8* rpc_create_cookie() return ret; } -boolean rpc_out_send_CONN_A1(rdpRpc* rpc) +void rpc_generate_cookie(uint8* cookie) +{ + RAND_pseudo_bytes(cookie, 16); +} + +boolean rpc_send_CONN_A1_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; uint32 ReceiveWindowSize; + uint8* OUTChannelCookie; + uint8* VirtualConnectionCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; @@ -373,15 +380,18 @@ boolean rpc_out_send_CONN_A1(rdpRpc* rpc) DEBUG_RPC("Sending CONN_A1"); 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; + + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->Cookie)); + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); + + VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); + OUTChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); + ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; 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_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ stream_seal(s); @@ -392,11 +402,13 @@ boolean rpc_out_send_CONN_A1(rdpRpc* rpc) return true; } -boolean rpc_in_send_CONN_B1(rdpRpc* rpc) +boolean rpc_send_CONN_B1_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; + uint8* INChannelCookie; uint8* AssociationGroupId; + uint8* VirtualConnectionCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; @@ -415,15 +427,20 @@ boolean rpc_in_send_CONN_B1(rdpRpc* rpc) DEBUG_RPC("Sending CONN_B1"); s = stream_new(header.frag_length); - rpc->INChannelCookie = rpc_create_cookie(); /* 16 bytes */ - AssociationGroupId = rpc_create_cookie(); /* 16 bytes */ + + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie)); + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->AssociationGroupId)); + + VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); + INChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie); + AssociationGroupId = (uint8*) &(rpc->VirtualConnection->AssociationGroupId); 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) */ + rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */ rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ - rts_client_keepalive_command_write(s, 0x000493e0); /* ClientKeepalive (8 bytes) */ + rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */ rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ stream_seal(s); @@ -434,7 +451,7 @@ boolean rpc_in_send_CONN_B1(rdpRpc* rpc) return true; } -boolean rpc_in_send_keep_alive(rdpRpc* rpc) +boolean rpc_send_keep_alive_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; @@ -646,10 +663,13 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) return true; } -boolean rpc_in_send_flow_control(rdpRpc* rpc) +boolean rpc_send_flow_control_ack_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; + uint32 BytesReceived; + uint32 AvailableWindow; + uint8* ChannelCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; @@ -665,14 +685,16 @@ boolean rpc_in_send_flow_control(rdpRpc* rpc) header.flags = 2; header.numberOfCommands = 2; - rpc->AwailableWindow = 0x00010000; + BytesReceived = rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived; + AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; + ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); s = stream_new(header.frag_length); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ /* FlowControlAck Command (28 bytes) */ - rts_flow_control_ack_command_write(s, rpc->BytesReceived, rpc->AwailableWindow, rpc->OUTChannelCookie); + rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie); stream_seal(s); @@ -683,7 +705,7 @@ boolean rpc_in_send_flow_control(rdpRpc* rpc) return true; } -boolean rpc_in_send_ping(rdpRpc* rpc) +boolean rpc_send_ping_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; @@ -733,8 +755,8 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) uint16 frag_length; rdpTls* tls_out = rpc->tls_out; - if (rpc->AwailableWindow < 0x00008FFF) /* Just a simple workaround */ - rpc_in_send_flow_control(rpc); /* Send FlowControlAck every time AW reaches the half */ + if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */ + rpc_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AW reaches the half */ pdu = xmalloc(0xFFFF); @@ -767,8 +789,9 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) } else { - rpc->BytesReceived += frag_length; /* RTS PDUs are not subjects for FlowControl */ - rpc->AwailableWindow -= frag_length; + /* RTS PDUs are not subject to flow control */ + rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived += frag_length; + rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= frag_length; } if (length < frag_length) @@ -829,6 +852,7 @@ int rpc_out_recv_bind_ack(rdpRpc* rpc) int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) { int i; + rdpBlob rdpMsg; int status = -1; rpcconn_request_hdr_t* request_pdu; @@ -883,7 +907,6 @@ int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) stream_write(pdu, &request_pdu->auth_verifier.auth_type, 8); - rdpBlob rdpMsg; rdpMsg.data = pdu->data; rdpMsg.length = stream_get_length(pdu); @@ -947,7 +970,8 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) else if (status < 0) { printf("Error! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", - rpc->BytesSent, rpc->BytesReceived); + rpc->VirtualConnection->DefaultInChannel->BytesSent, + rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived); xfree(rpc_data); return status; @@ -996,7 +1020,7 @@ boolean rpc_connect(rdpRpc* rpc) uint8* pdu; int pdu_length; - if (!rpc_out_send_CONN_A1(rpc)) + if (!rpc_send_CONN_A1_pdu(rpc)) { printf("rpc_out_send_CONN_A1 fault!\n"); return false; @@ -1007,9 +1031,9 @@ boolean rpc_connect(rdpRpc* rpc) status = rpc_out_read(rpc, pdu, pdu_length); - if (!rpc_in_send_CONN_B1(rpc)) + if (!rpc_send_CONN_B1_pdu(rpc)) { - printf("rpc_out_send_CONN_A1 fault!\n"); + printf("rpc_out_send_CONN_B1 fault!\n"); return false; } @@ -1040,6 +1064,40 @@ boolean rpc_connect(rdpRpc* rpc) return true; } +void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* virtual_connection) +{ + virtual_connection->DefaultInChannel->BytesSent = 0; + virtual_connection->DefaultOutChannel->RecipientBytesReceived = 0; + virtual_connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow; + virtual_connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow; + virtual_connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow; + virtual_connection->DefaultInChannel->SenderAvailableWindow = rpc->ReceiveWindow; + virtual_connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30; + virtual_connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0; +} + +RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc) +{ + RpcVirtualConnection* virtual_connection = xnew(RpcVirtualConnection); + + if (virtual_connection != NULL) + { + virtual_connection->DefaultInChannel = xnew(RpcInChannel); + virtual_connection->DefaultOutChannel = xnew(RpcOutChannel); + rpc_client_virtual_connection_init(rpc, virtual_connection); + } + + return virtual_connection; +} + +void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection) +{ + if (virtual_connection != NULL) + { + xfree(virtual_connection); + } +} + rdpRpc* rpc_new(rdpSettings* settings) { rdpRpc* rpc = (rdpRpc*) xnew(rdpRpc); @@ -1082,10 +1140,8 @@ rdpRpc* rpc_new(rdpSettings* settings) rpc->read_buffer_len = 0; rpc->write_buffer_len = 0; - rpc->BytesReceived = 0; - rpc->AwailableWindow = 0; - rpc->BytesSent = 0; - rpc->RecAwailableWindow = 0; + rpc->ReceiveWindow = 0x00010000; + rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); rpc->settings = settings; diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 4c2f88f09..986fe544b 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -553,6 +553,66 @@ struct rdp_rpc_http rdpNtlm* ntlm; }; +/* Ping Originator */ + +struct rpc_ping_originator +{ + uint32 ConnectionTimeout; + uint32 LastPacketSentTimestamp; + uint32 KeepAliveInterval; +}; +typedef struct rpc_ping_originator RpcPingOriginator; + +/* Client In Channel */ + +struct rpc_in_channel +{ + /* Sending Channel */ + + uint32 PlugState; + void* SendQueue; + uint32 BytesSent; + uint32 SenderAvailableWindow; + uint32 PeerReceiveWindow; + + /* Ping Originator */ + + RpcPingOriginator PingOriginator; +}; +typedef struct rpc_in_channel RpcInChannel; + +/* Client Out Channel */ + +struct rpc_out_channel +{ + /* Receiving Channel */ + + uint32 ReceiveWindow; + uint32 ReceiveWindowSize; + uint32 ReceiverAvailableWindow; + uint32 RecipientBytesReceived; + uint32 AvailableWindowAdvertised; +}; +typedef struct rpc_out_channel RpcOutChannel; + +/* Client Virtual Connection */ + +struct rpc_virtual_connection +{ + uint8 Cookie[16]; /* Virtual Connection Cookie */ + uint32 State; /* Virtual Connection State */ + RpcInChannel* DefaultInChannel; /* Default IN Channel */ + RpcInChannel* NonDefaultInChannel; /* Non-Default IN Channel */ + uint8 DefaultInChannelCookie[16]; /* Default IN Channel Cookie */ + uint8 NonDefaultInChannelCookie[16]; /* Non-Default Default IN Channel Cookie */ + RpcOutChannel* DefaultOutChannel; /* Default OUT Channel */ + RpcOutChannel* NonDefaultOutChannel; /* Non-Default OUT Channel */ + uint8 DefaultOutChannelCookie[16]; /* Default OUT Channel Cookie */ + uint8 NonDefaultOutChannelCookie[16]; /* Non-Default Default OUT Channel Cookie */ + uint8 AssociationGroupId[16]; /* AssociationGroupId */ +}; +typedef struct rpc_virtual_connection RpcVirtualConnection; + struct rdp_rpc { rdpTcp* tcp_in; @@ -572,13 +632,10 @@ struct rdp_rpc uint8* read_buffer; uint32 read_buffer_len; - uint32 BytesReceived; - uint32 AwailableWindow; - uint32 BytesSent; - uint32 RecAwailableWindow; - uint8* virtualConnectionCookie; - uint8* OUTChannelCookie; - uint8* INChannelCookie; + uint32 ReceiveWindow; + + RpcVirtualConnection* VirtualConnection; + uint32 call_id; uint32 pipe_call_id; }; @@ -594,7 +651,7 @@ void ntlm_free(rdpNtlm* ntlm); 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); +boolean rpc_send_keep_alive_pdu(rdpRpc* rpc); int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); int rpc_read(rdpRpc* rpc, uint8* data, int length); diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index b948e9626..bc6b39948 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -284,7 +284,7 @@ int rts_pdu_recv(rdpRpc* rpc, STREAM* s) if (header.flags & RTS_FLAG_PING) { - rpc_in_send_keep_alive(rpc); + rpc_send_keep_alive_pdu(rpc); return 0; } From 25efe0f20f3ac60be29c5c3daa596066facec434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 13:45:25 -0400 Subject: [PATCH 21/47] libfreerdp-core: perform HTTP authentication in a separate step instead of implicitly --- libfreerdp-core/rpc.c | 54 ++++++++++++++++++++++--------------------- libfreerdp-core/rpc.h | 9 -------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 6aef8cca6..e7a5e78df 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -247,8 +247,6 @@ boolean rpc_out_connect_http(rdpRpc* rpc) /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ - http_out->state = RPC_HTTP_SENDING; - return true; } @@ -289,8 +287,6 @@ boolean rpc_in_connect_http(rdpRpc* rpc) /* At this point IN connection is ready to send CONN/B1 and start with sending data */ - http_in->state = RPC_HTTP_SENDING; - return true; } @@ -298,13 +294,6 @@ int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { int status; rdpTls* tls_out = rpc->tls_out; - rdpRpcHTTP* http_out = rpc->http_out; - - if (http_out->state == RPC_HTTP_DISCONNECTED) - { - if (!rpc_out_connect_http(rpc)) - return false; - } #ifdef WITH_DEBUG_RPC printf("rpc_out_write(): length: %d\n", length); @@ -321,13 +310,6 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length) { int status; rdpTls* tls_in = rpc->tls_in; - rdpRpcHTTP* http_in = rpc->http_in; - - if (http_in->state == RPC_HTTP_DISCONNECTED) - { - if (!rpc_in_connect_http(rpc)) - return -1; - } #ifdef WITH_DEBUG_RPC printf("rpc_in_write() length: %d\n", length); @@ -377,7 +359,7 @@ boolean rpc_send_CONN_A1_pdu(rdpRpc* rpc) header.flags = 0; header.numberOfCommands = 4; - DEBUG_RPC("Sending CONN_A1"); + DEBUG_RPC("Sending CONN_A1 RTS PDU"); s = stream_new(header.frag_length); @@ -424,7 +406,7 @@ boolean rpc_send_CONN_B1_pdu(rdpRpc* rpc) header.flags = 0; header.numberOfCommands = 6; - DEBUG_RPC("Sending CONN_B1"); + DEBUG_RPC("Sending CONN_B1 RTS PDU"); s = stream_new(header.frag_length); @@ -470,6 +452,8 @@ boolean rpc_send_keep_alive_pdu(rdpRpc* rpc) header.flags = 2; header.numberOfCommands = 1; + DEBUG_RPC("Sending Keep-Alive RTS PDU"); + 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) */ @@ -493,6 +477,8 @@ boolean rpc_in_send_bind(rdpRpc* rpc) rpc->ntlm = ntlm_new(); + DEBUG_RPC("Sending bind PDU"); + DEBUG_RPC("TODO: complete NTLM integration"); ntlm_client_init(rpc->ntlm, false, settings->username, settings->domain, settings->password); @@ -617,6 +603,8 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); + DEBUG_RPC("Sending auth3 PDU"); + ntlm_authenticate(rpc->ntlm); ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer; @@ -685,6 +673,8 @@ boolean rpc_send_flow_control_ack_pdu(rdpRpc* rpc) header.flags = 2; header.numberOfCommands = 2; + DEBUG_RPC("Sending FlowControlAck RTS PDU"); + BytesReceived = rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived; AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); @@ -724,6 +714,8 @@ boolean rpc_send_ping_pdu(rdpRpc* rpc) header.flags = 1; header.numberOfCommands = 0; + DEBUG_RPC("Sending Ping RTS PDU"); + s = stream_new(header.frag_length); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ stream_seal(s); @@ -924,7 +916,7 @@ int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) if (status < 0) { - printf("rpc_write(): Error! rcph_in_write returned negative value.\n"); + printf("rpc_write(): Error! rcp_in_write returned negative value.\n"); return status; } @@ -1020,9 +1012,15 @@ boolean rpc_connect(rdpRpc* rpc) uint8* pdu; int pdu_length; + if (!rpc_out_connect_http(rpc)) + { + printf("rpc_out_connect_http error!\n"); + return false; + } + if (!rpc_send_CONN_A1_pdu(rpc)) { - printf("rpc_out_send_CONN_A1 fault!\n"); + printf("rpc_send_CONN_A1_pdu error!\n"); return false; } @@ -1031,9 +1029,15 @@ boolean rpc_connect(rdpRpc* rpc) status = rpc_out_read(rpc, pdu, pdu_length); + if (!rpc_in_connect_http(rpc)) + { + printf("rpc_in_connect_http error!\n"); + return false; + } + if (!rpc_send_CONN_B1_pdu(rpc)) { - printf("rpc_out_send_CONN_B1 fault!\n"); + printf("rpc_send_CONN_B1_pdu error!\n"); return false; } @@ -1044,7 +1048,7 @@ boolean rpc_connect(rdpRpc* rpc) */ if (!rpc_in_send_bind(rpc)) { - printf("rpc_out_send_bind fault!\n"); + printf("rpc_in_send_bind fault!\n"); return false; } @@ -1109,8 +1113,6 @@ rdpRpc* rpc_new(rdpSettings* settings) rpc->http_in->ntlm = ntlm_new(); rpc->http_out->ntlm = ntlm_new(); - rpc->http_in->state = RPC_HTTP_DISCONNECTED; - rpc->http_out->state = RPC_HTTP_DISCONNECTED; rpc->http_in->context = http_context_new(); http_context_set_method(rpc->http_in->context, "RPC_IN_DATA"); diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 986fe544b..b3399b733 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -538,17 +538,8 @@ struct rdp_ntlm }; typedef struct rdp_ntlm rdpNtlm; -enum _RPC_HTTP_STATE -{ - RPC_HTTP_DISCONNECTED = 0, - RPC_HTTP_SENDING = 1, - RPC_HTTP_RECEIVING = 2 -}; -typedef enum _RPC_HTTP_STATE RPC_HTTP_STATE; - struct rdp_rpc_http { - RPC_HTTP_STATE state; HttpContext* context; rdpNtlm* ntlm; }; From 2e5215ba3af2b76c7a385af3a70c7e1ca9768dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 14:27:13 -0400 Subject: [PATCH 22/47] libfreerdp-core: document MS-RPCH connection establishment --- libfreerdp-core/rpc.c | 49 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index e7a5e78df..28ed6345f 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -227,9 +227,13 @@ boolean rpc_out_connect_http(rdpRpc* rpc) s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); + /* Send OUT Channel Request */ + DEBUG_RPC("\n%s", s->data); tls_write_all(tls_out, s->data, s->size); + /* Receive OUT Channel Response */ + http_response = http_response_recv(tls_out); crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), @@ -242,6 +246,8 @@ boolean rpc_out_connect_http(rdpRpc* rpc) s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 76); + /* Send OUT Channel Request */ + DEBUG_RPC("\n%s", s->data); tls_write_all(tls_out, s->data, s->size); @@ -267,9 +273,13 @@ boolean rpc_in_connect_http(rdpRpc* rpc) http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); + /* Send IN Channel Request */ + DEBUG_RPC("\n%s", http_stream->data); tls_write_all(tls_in, http_stream->data, http_stream->size); + /* Receive IN Channel Response */ + http_response = http_response_recv(tls_in); crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), @@ -282,6 +292,8 @@ boolean rpc_in_connect_http(rdpRpc* rpc) http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0x40000000); + /* Send IN Channel Request */ + DEBUG_RPC("\n%s", http_stream->data); tls_write_all(tls_in, http_stream->data, http_stream->size); @@ -1006,12 +1018,37 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) return read; } +/** + * Connection Establishment\n + * + * Client Outbound Proxy Inbound Proxy Server\n + * | | | |\n + * |-----------------IN Channel Request--------------->| |\n + * |---OUT Channel Request-->| |<-Legacy Server Response-|\n + * | |<--------------Legacy Server Response--------------|\n + * | | | |\n + * |---------CONN_A1-------->| | |\n + * |----------------------CONN_B1--------------------->| |\n + * | |----------------------CONN_A2--------------------->|\n + * | | | |\n + * |<--OUT Channel Response--| |---------CONN_B2-------->|\n + * |<--------CONN_A3---------| | |\n + * | |<---------------------CONN_C1----------------------|\n + * | | |<--------CONN_B3---------|\n + * |<--------CONN_C2---------| | |\n + * | | | |\n + * + */ + boolean rpc_connect(rdpRpc* rpc) { int status; uint8* pdu; int pdu_length; + pdu_length = 0xFFFF; + pdu = xmalloc(pdu_length); + if (!rpc_out_connect_http(rpc)) { printf("rpc_out_connect_http error!\n"); @@ -1024,11 +1061,6 @@ boolean rpc_connect(rdpRpc* rpc) return false; } - pdu_length = 0xFFFF; - pdu = xmalloc(pdu_length); - - status = rpc_out_read(rpc, pdu, pdu_length); - if (!rpc_in_connect_http(rpc)) { printf("rpc_in_connect_http error!\n"); @@ -1041,6 +1073,13 @@ boolean rpc_connect(rdpRpc* rpc) return false; } + /* Receive OUT Channel Response */ + status = rpc_out_read(rpc, pdu, pdu_length); + + /* Receive CONN_A3 RTS PDU */ + status = rpc_out_read(rpc, pdu, pdu_length); + + /* Receive CONN_C2 RTS PDU */ status = rpc_out_read(rpc, pdu, pdu_length); /* [MS-RPCH] 3.2.1.5.3.1 Connection Establishment From 3b37d2262a43b6d1ceb76ed4c7ecb8e331f871ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 16:18:07 -0400 Subject: [PATCH 23/47] libfreerdp-core: separate RTS and RPC PDU receiving --- libfreerdp-core/http.c | 11 ++ libfreerdp-core/http.h | 2 + libfreerdp-core/rpc.c | 440 +++++++++-------------------------------- libfreerdp-core/rpc.h | 36 +++- libfreerdp-core/rts.c | 358 ++++++++++++++++++++++++++++++++- libfreerdp-core/rts.h | 17 +- 6 files changed, 505 insertions(+), 359 deletions(-) diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c index ddba2c17c..985d185ff 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp-core/http.c @@ -287,6 +287,17 @@ void http_response_parse_header(HttpResponse* http_response) } } +void http_response_print(HttpResponse* http_response) +{ + int i; + + for (i = 0; i < http_response->count; i++) + { + printf("%s\n", http_response->lines[i]); + } + printf("\n"); +} + HttpResponse* http_response_recv(rdpTls* tls) { uint8* p; diff --git a/libfreerdp-core/http.h b/libfreerdp-core/http.h index 06f50e97d..2b3bee83c 100644 --- a/libfreerdp-core/http.h +++ b/libfreerdp-core/http.h @@ -91,6 +91,8 @@ struct _http_response char* Content; }; +void http_response_print(HttpResponse* http_response); + HttpResponse* http_response_recv(rdpTls* tls); HttpResponse* http_response_new(); diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 28ed6345f..7bff866f1 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -302,6 +302,21 @@ boolean rpc_in_connect_http(rdpRpc* rpc) return true; } +void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header) +{ + stream_read_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */ + stream_read_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */ + stream_read_uint8(s, header->ptype); /* PTYPE (1 byte) */ + stream_read_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */ + stream_read_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */ + stream_read_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */ + stream_read_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */ + stream_read_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */ + stream_read_uint16(s, header->frag_length); /* frag_length (2 bytes) */ + stream_read_uint16(s, header->auth_length); /* auth_length (2 bytes) */ + stream_read_uint32(s, header->call_id); /* call_id (4 bytes) */ +} + int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { int status; @@ -337,148 +352,7 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length) return status; } -uint8* rpc_create_cookie() -{ - uint8* ret = xmalloc(16); - RAND_pseudo_bytes(ret, 16); - return ret; -} - -void rpc_generate_cookie(uint8* cookie) -{ - RAND_pseudo_bytes(cookie, 16); -} - -boolean rpc_send_CONN_A1_pdu(rdpRpc* rpc) -{ - STREAM* s; - RTS_PDU_HEADER header; - uint32 ReceiveWindowSize; - uint8* OUTChannelCookie; - uint8* VirtualConnectionCookie; - - 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 RTS PDU"); - - s = stream_new(header.frag_length); - - rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->Cookie)); - rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); - - VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); - OUTChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); - ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; - - rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ - rts_version_command_write(s); /* Version (8 bytes) */ - rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ - rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ - rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ - stream_seal(s); - - rpc_out_write(rpc, s->data, s->size); - - stream_free(s); - - return true; -} - -boolean rpc_send_CONN_B1_pdu(rdpRpc* rpc) -{ - STREAM* s; - RTS_PDU_HEADER header; - uint8* INChannelCookie; - uint8* AssociationGroupId; - uint8* VirtualConnectionCookie; - - 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 RTS PDU"); - - s = stream_new(header.frag_length); - - rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie)); - rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->AssociationGroupId)); - - VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); - INChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie); - AssociationGroupId = (uint8*) &(rpc->VirtualConnection->AssociationGroupId); - - rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ - rts_version_command_write(s); /* Version (8 bytes) */ - rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ - rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */ - rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ - rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */ - rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ - stream_seal(s); - - rpc_in_write(rpc, s->data, s->size); - - stream_free(s); - - return true; -} - -boolean rpc_send_keep_alive_pdu(rdpRpc* rpc) -{ - 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; - - DEBUG_RPC("Sending Keep-Alive RTS PDU"); - - 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, s->size); - - stream_free(s); - - return true; -} - -boolean rpc_in_send_bind(rdpRpc* rpc) +boolean rpc_send_bind_pdu(rdpRpc* rpc) { STREAM* pdu; rpcconn_bind_hdr_t* bind_pdu; @@ -609,13 +483,50 @@ boolean rpc_in_send_bind(rdpRpc* rpc) return true; } -boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) +int rpc_recv_bind_ack_pdu(rdpRpc* rpc) +{ + STREAM* s; + uint16 frag_length; + uint16 auth_length; + STREAM* ntlmssp_stream; + RPC_PDU_HEADER header; + int pdu_length = 0x8FFF; /* 32KB buffer */ + uint8* pdu = xmalloc(pdu_length); + int status = rpc_out_read(rpc, pdu, pdu_length); + + DEBUG_RPC("TODO: complete NTLM integration"); + + if (status > 0) + { + s = stream_new(0); + stream_attach(s, pdu, pdu_length); + rpc_pdu_header_read(s, &header); + + frag_length = header.frag_length; + auth_length = header.auth_length; + + printf("frag_length:%d auth_length:%d\n", frag_length, auth_length); + + ntlmssp_stream = stream_new(0xFFFF); + stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); + ntlmssp_stream->p = ntlmssp_stream->data; + + //ntlmssp_recv(rpc->ntlmssp, ntlmssp_stream); + + stream_free(ntlmssp_stream); + } + + xfree(pdu); + return status; +} + +boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) { STREAM* pdu; rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; STREAM* ntlm_stream = stream_new(0xFFFF); - DEBUG_RPC("Sending auth3 PDU"); + DEBUG_RPC("Sending auth_3 PDU"); ntlm_authenticate(rpc->ntlm); ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; @@ -633,6 +544,7 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) rpc_auth_3_pdu->frag_length = 28 + ntlm_stream->size; rpc_auth_3_pdu->auth_length = ntlm_stream->size; rpc_auth_3_pdu->call_id = 2; + rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; rpc_auth_3_pdu->max_recv_frag = 0x0FF8; rpc_auth_3_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p */ @@ -663,82 +575,6 @@ boolean rpc_in_send_rpc_auth_3(rdpRpc* rpc) return true; } -boolean rpc_send_flow_control_ack_pdu(rdpRpc* rpc) -{ - STREAM* s; - RTS_PDU_HEADER header; - uint32 BytesReceived; - uint32 AvailableWindow; - uint8* ChannelCookie; - - 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 = 56; - header.auth_length = 0; - header.call_id = 0; - header.flags = 2; - header.numberOfCommands = 2; - - DEBUG_RPC("Sending FlowControlAck RTS PDU"); - - BytesReceived = rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived; - AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; - ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); - - s = stream_new(header.frag_length); - rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ - rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ - - /* FlowControlAck Command (28 bytes) */ - rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie); - - stream_seal(s); - - rpc_in_write(rpc, s->data, s->size); - - stream_free(s); - - return true; -} - -boolean rpc_send_ping_pdu(rdpRpc* rpc) -{ - 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 = 20; - header.auth_length = 0; - header.call_id = 0; - header.flags = 1; - header.numberOfCommands = 0; - - DEBUG_RPC("Sending Ping RTS PDU"); - - s = stream_new(header.frag_length); - rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ - stream_seal(s); - - rpc_in_write(rpc, s->data, s->size); - - stream_free(s); - - return true; -} - int rpc_out_read_http_header(rdpRpc* rpc) { int status = 0; @@ -755,27 +591,33 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) STREAM* s; int status; uint8* pdu; - uint8 ptype; - uint16 frag_length; + int content_length; + RPC_PDU_HEADER header; rdpTls* tls_out = rpc->tls_out; if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */ - rpc_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AW reaches the half */ + rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */ pdu = xmalloc(0xFFFF); - status = tls_read(tls_out, pdu, 10); + status = tls_read(tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */ - if (status <= 0) /* read first 10 bytes to get the frag_length value */ + if (status <= 0) { xfree(pdu); return status; } - ptype = *(pdu + 2); - frag_length = *((uint16*) (pdu + 8)); + s = stream_new(0); + stream_attach(s, pdu, 16); - status = tls_read(tls_out, pdu + 10, frag_length - 10); + rpc_pdu_header_read(s, &header); + + stream_detach(s); + stream_free(s); + + content_length = header.frag_length - 16; + status = tls_read(tls_out, pdu + 16, content_length); if (status < 0) { @@ -783,74 +625,35 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) return status; } - if (ptype == PTYPE_RTS) /* RTS PDU */ + if (header.ptype == PTYPE_RTS) /* RTS PDU */ { - s = stream_new(0); - stream_attach(s, pdu, frag_length); - rts_pdu_recv(rpc, s); - xfree(pdu); - return 0; + printf("rpc_out_read error: Unexpected RTS PDU\n"); + return -1; } else { /* RTS PDUs are not subject to flow control */ - rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived += frag_length; - rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= frag_length; + rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived += header.frag_length; + rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length; } - if (length < frag_length) + if (length < header.frag_length) { - printf("rpc_out_read(): Error! Given buffer is to small. Received data fits not in.\n"); - xfree(pdu); - return -1; /* TODO add buffer for storing remaining data for the next read in case destination buffer is too small */ - } - - memcpy(data, pdu, frag_length); - - if (strncmp((char*) pdu, "HTTP", 4) == 0) - { - printf("\n%s", (char*) pdu); + printf("rpc_out_read error! receive buffer is not large enough\n"); return -1; } + memcpy(data, pdu, header.frag_length); + #ifdef WITH_DEBUG_RPC - printf("rpc_out_read(): length: %d\n", frag_length); - freerdp_hexdump(data, frag_length); + printf("rpc_out_read(): length: %d\n", header.frag_length); + freerdp_hexdump(data, header.frag_length); printf("\n"); #endif xfree(pdu); - return frag_length; -} - -int rpc_out_recv_bind_ack(rdpRpc* rpc) -{ - uint16 frag_length; - uint16 auth_length; - STREAM* ntlmssp_stream; - int pdu_length = 0x8FFF; /* 32KB buffer */ - uint8* pdu = xmalloc(pdu_length); - int status = rpc_out_read(rpc, pdu, pdu_length); - - DEBUG_RPC("TODO: complete NTLM integration"); - - if (status > 0) - { - frag_length = *((uint16*)(pdu + 8)); - auth_length = *((uint16*)(pdu + 10)); - - ntlmssp_stream = stream_new(0xFFFF); - stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); - ntlmssp_stream->p = ntlmssp_stream->data; - - //ntlmssp_recv(rpc->ntlmssp, ntlmssp_stream); - - stream_free(ntlmssp_stream); - } - - xfree(pdu); - return status; + return header.frag_length; } int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) @@ -928,7 +731,7 @@ int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) if (status < 0) { - printf("rpc_write(): Error! rcp_in_write returned negative value.\n"); + printf("rpc_write(): Error! rpc_in_write returned negative value.\n"); return status; } @@ -1018,92 +821,32 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) return read; } -/** - * Connection Establishment\n - * - * Client Outbound Proxy Inbound Proxy Server\n - * | | | |\n - * |-----------------IN Channel Request--------------->| |\n - * |---OUT Channel Request-->| |<-Legacy Server Response-|\n - * | |<--------------Legacy Server Response--------------|\n - * | | | |\n - * |---------CONN_A1-------->| | |\n - * |----------------------CONN_B1--------------------->| |\n - * | |----------------------CONN_A2--------------------->|\n - * | | | |\n - * |<--OUT Channel Response--| |---------CONN_B2-------->|\n - * |<--------CONN_A3---------| | |\n - * | |<---------------------CONN_C1----------------------|\n - * | | |<--------CONN_B3---------|\n - * |<--------CONN_C2---------| | |\n - * | | | |\n - * - */ - boolean rpc_connect(rdpRpc* rpc) { - int status; - uint8* pdu; - int pdu_length; - - pdu_length = 0xFFFF; - pdu = xmalloc(pdu_length); - - if (!rpc_out_connect_http(rpc)) + if (!rts_connect(rpc)) { - printf("rpc_out_connect_http error!\n"); + printf("rts_connect error!\n"); return false; } - if (!rpc_send_CONN_A1_pdu(rpc)) + if (!rpc_send_bind_pdu(rpc)) { - printf("rpc_send_CONN_A1_pdu error!\n"); + printf("rpc_send_bind_pdu error!\n"); return false; } - if (!rpc_in_connect_http(rpc)) + if (!rpc_recv_bind_ack_pdu(rpc)) { - printf("rpc_in_connect_http error!\n"); + printf("rpc_recv_bind_ack_pdu error!\n"); return false; } - if (!rpc_send_CONN_B1_pdu(rpc)) + if (!rpc_send_rpc_auth_3_pdu(rpc)) { - printf("rpc_send_CONN_B1_pdu error!\n"); + printf("rpc_send_rpc_auth_3 error!\n"); return false; } - /* Receive OUT Channel Response */ - status = rpc_out_read(rpc, pdu, pdu_length); - - /* Receive CONN_A3 RTS PDU */ - status = rpc_out_read(rpc, pdu, pdu_length); - - /* Receive CONN_C2 RTS PDU */ - status = rpc_out_read(rpc, pdu, pdu_length); - - /* [MS-RPCH] 3.2.1.5.3.1 Connection Establishment - * at this point VirtualChannel is created - */ - if (!rpc_in_send_bind(rpc)) - { - printf("rpc_in_send_bind fault!\n"); - return false; - } - - if (!rpc_out_recv_bind_ack(rpc)) - { - printf("rpc_out_recv_bind_ack fault!\n"); - return false; - } - - if (!rpc_in_send_rpc_auth_3(rpc)) - { - printf("rpc_out_send_rpc_auth_3 fault!\n"); - return false; - } - - xfree(pdu); return true; } @@ -1125,6 +868,7 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc) if (virtual_connection != NULL) { + virtual_connection->State = VIRTUAL_CONNECTION_STATE_INITIAL; virtual_connection->DefaultInChannel = xnew(RpcInChannel); virtual_connection->DefaultOutChannel = xnew(RpcOutChannel); rpc_client_virtual_connection_init(rpc, virtual_connection); diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index b3399b733..352953bbc 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -41,6 +41,19 @@ typedef struct rdp_rpc_http rdpRpcHTTP; #include #include +struct _rpc_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; +}; +typedef struct _rpc_pdu_header RPC_PDU_HEADER; + typedef uint16 p_context_id_t; typedef struct { @@ -588,10 +601,21 @@ typedef struct rpc_out_channel RpcOutChannel; /* Client Virtual Connection */ +enum _VIRTUAL_CONNECTION_STATE +{ + VIRTUAL_CONNECTION_STATE_INITIAL, + VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT, + VIRTUAL_CONNECTION_STATE_WAIT_A3W, + VIRTUAL_CONNECTION_STATE_WAIT_C2, + VIRTUAL_CONNECTION_STATE_OPENED, + VIRTUAL_CONNECTION_STATE_FINAL +}; +typedef enum _VIRTUAL_CONNECTION_STATE VIRTUAL_CONNECTION_STATE; + struct rpc_virtual_connection { uint8 Cookie[16]; /* Virtual Connection Cookie */ - uint32 State; /* Virtual Connection State */ + VIRTUAL_CONNECTION_STATE State; /* Virtual Connection State */ RpcInChannel* DefaultInChannel; /* Default IN Channel */ RpcInChannel* NonDefaultInChannel; /* Non-Default IN Channel */ uint8 DefaultInChannelCookie[16]; /* Default IN Channel Cookie */ @@ -642,7 +666,15 @@ void ntlm_free(rdpNtlm* ntlm); boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); boolean rpc_connect(rdpRpc* rpc); -boolean rpc_send_keep_alive_pdu(rdpRpc* rpc); +boolean rpc_out_connect_http(rdpRpc* rpc); +boolean rpc_in_connect_http(rdpRpc* rpc); + +void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header); + +int rpc_out_write(rdpRpc* rpc, uint8* data, int length); +int rpc_in_write(rdpRpc* rpc, uint8* data, int length); + +int rpc_out_read(rdpRpc* rpc, uint8* data, int length); int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); int rpc_read(rdpRpc* rpc, uint8* data, int length); diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index bc6b39948..618cfa2de 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -19,6 +19,81 @@ #include "rts.h" +/** + * Connection Establishment\n + * + * Client Outbound Proxy Inbound Proxy Server\n + * | | | |\n + * |-----------------IN Channel Request--------------->| |\n + * |---OUT Channel Request-->| |<-Legacy Server Response-|\n + * | |<--------------Legacy Server Response--------------|\n + * | | | |\n + * |---------CONN_A1-------->| | |\n + * |----------------------CONN_B1--------------------->| |\n + * | |----------------------CONN_A2--------------------->|\n + * | | | |\n + * |<--OUT Channel Response--| |---------CONN_B2-------->|\n + * |<--------CONN_A3---------| | |\n + * | |<---------------------CONN_C1----------------------|\n + * | | |<--------CONN_B3---------|\n + * |<--------CONN_C2---------| | |\n + * | | | |\n + * + */ + +boolean rts_connect(rdpRpc* rpc) +{ + int status; + RTS_PDU rts_pdu; + HttpResponse* http_response; + + if (!rpc_out_connect_http(rpc)) + { + printf("rpc_out_connect_http error!\n"); + return false; + } + + if (!rts_send_CONN_A1_pdu(rpc)) + { + printf("rpc_send_CONN_A1_pdu error!\n"); + return false; + } + + if (!rpc_in_connect_http(rpc)) + { + printf("rpc_in_connect_http error!\n"); + return false; + } + + if (!rts_send_CONN_B1_pdu(rpc)) + { + printf("rpc_send_CONN_B1_pdu error!\n"); + return false; + } + + /* Receive OUT Channel Response */ + http_response = http_response_recv(rpc->tls_out); + + if (http_response->StatusCode != 200) + { + printf("rts_connect error!\n"); + http_response_print(http_response); + return false; + } + + http_response_print(http_response); + + http_response_free(http_response); + + /* Receive CONN_A3 RTS PDU */ + status = rts_recv_pdu(rpc, &rts_pdu); + + /* Receive CONN_C2 RTS PDU */ + status = rts_recv_pdu(rpc, &rts_pdu); + + return true; +} + #ifdef WITH_DEBUG_RTS static const char* const RTS_CMD_STRINGS[] = @@ -272,23 +347,234 @@ void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSen stream_write_uint32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */ } -int rts_pdu_recv(rdpRpc* rpc, STREAM* s) +void rpc_generate_cookie(uint8* cookie) { - int i; - uint32 CommandType; + RAND_pseudo_bytes(cookie, 16); +} + +boolean rts_send_CONN_A1_pdu(rdpRpc* rpc) +{ + STREAM* s; + RTS_PDU_HEADER header; + uint32 ReceiveWindowSize; + uint8* OUTChannelCookie; + uint8* VirtualConnectionCookie; + + 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 RTS PDU"); + + s = stream_new(header.frag_length); + + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->Cookie)); + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); + + VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); + OUTChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); + ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; + + rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ + rts_version_command_write(s); /* Version (8 bytes) */ + rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ + rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ + stream_seal(s); + + rpc_out_write(rpc, s->data, s->size); + + stream_free(s); + + return true; +} + +boolean rts_send_CONN_B1_pdu(rdpRpc* rpc) +{ + STREAM* s; + RTS_PDU_HEADER header; + uint8* INChannelCookie; + uint8* AssociationGroupId; + uint8* VirtualConnectionCookie; + + 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 RTS PDU"); + + s = stream_new(header.frag_length); + + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie)); + rpc_generate_cookie((uint8*) &(rpc->VirtualConnection->AssociationGroupId)); + + VirtualConnectionCookie = (uint8*) &(rpc->VirtualConnection->Cookie); + INChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultInChannelCookie); + AssociationGroupId = (uint8*) &(rpc->VirtualConnection->AssociationGroupId); + + rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ + rts_version_command_write(s); /* Version (8 bytes) */ + rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */ + rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ + rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */ + rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ + stream_seal(s); + + rpc_in_write(rpc, s->data, s->size); + + stream_free(s); + + return true; +} + +boolean rts_send_keep_alive_pdu(rdpRpc* rpc) +{ + STREAM* s; RTS_PDU_HEADER header; - rts_pdu_header_read(s, &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; - DEBUG_RTS("numberOfCommands:%d", header.numberOfCommands); + DEBUG_RPC("Sending Keep-Alive RTS PDU"); - if (header.flags & RTS_FLAG_PING) + 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, s->size); + + stream_free(s); + + return true; +} + +boolean rts_send_flow_control_ack_pdu(rdpRpc* rpc) +{ + STREAM* s; + RTS_PDU_HEADER header; + uint32 BytesReceived; + uint32 AvailableWindow; + uint8* ChannelCookie; + + 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 = 56; + header.auth_length = 0; + header.call_id = 0; + header.flags = 2; + header.numberOfCommands = 2; + + DEBUG_RPC("Sending FlowControlAck RTS PDU"); + + BytesReceived = rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived; + AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; + ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); + + s = stream_new(header.frag_length); + rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ + rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ + + /* FlowControlAck Command (28 bytes) */ + rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie); + + stream_seal(s); + + rpc_in_write(rpc, s->data, s->size); + + stream_free(s); + + return true; +} + +boolean rts_send_ping_pdu(rdpRpc* rpc) +{ + 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 = 20; + header.auth_length = 0; + header.call_id = 0; + header.flags = 1; + header.numberOfCommands = 0; + + DEBUG_RPC("Sending Ping RTS PDU"); + + s = stream_new(header.frag_length); + rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ + stream_seal(s); + + rpc_in_write(rpc, s->data, s->size); + + stream_free(s); + + return true; +} + +int rts_recv_pdu_commands(rdpRpc* rpc, RTS_PDU* rts_pdu) +{ + int i; + STREAM* s; + uint32 CommandType; + + s = stream_new(0); + stream_attach(s, rts_pdu->content, rts_pdu->header.frag_length); + + DEBUG_RTS("numberOfCommands:%d", rts_pdu->header.numberOfCommands); + + if (rts_pdu->header.flags & RTS_FLAG_PING) { - rpc_send_keep_alive_pdu(rpc); + rts_send_keep_alive_pdu(rpc); return 0; } - for (i = 0; i < header.numberOfCommands; i++) + for (i = 0; i < rts_pdu->header.numberOfCommands; i++) { stream_read_uint32(s, CommandType); /* CommandType (4 bytes) */ @@ -363,5 +649,61 @@ int rts_pdu_recv(rdpRpc* rpc, STREAM* s) } } + stream_detach(s); + stream_free(s); + return 0; } + +int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu) +{ + STREAM* s; + int status; + int length; + uint8 header_buffer[20]; + rdpTls* tls_out = rpc->tls_out; + + /* read first 20 bytes to get RTS PDU Header */ + status = tls_read(tls_out, (uint8*) &header_buffer, 20); + + if (status <= 0) + { + printf("rts_recv error\n"); + return status; + } + + s = stream_new(0); + stream_attach(s, header_buffer, 20); + + rts_pdu_header_read(s, &(rts_pdu->header)); + + stream_detach(s); + stream_free(s); + + length = rts_pdu->header.frag_length - 20; + rts_pdu->content = (uint8*) xmalloc(length); + + status = tls_read(tls_out, rts_pdu->content, length); + + if (status < 0) + { + printf("rts_recv error\n"); + return status; + } + + if (rts_pdu->header.ptype != PTYPE_RTS) + { + printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype); + return -1; + } + +#ifdef WITH_DEBUG_RTS + printf("rts_recv(): length: %d\n", length); + freerdp_hexdump(rts_pdu->content, length); + printf("\n"); +#endif + + rts_recv_pdu_commands(rpc, rts_pdu); + + return rts_pdu->header.frag_length; +} diff --git a/libfreerdp-core/rts.h b/libfreerdp-core/rts.h index ecd24344b..b7ce7ae2b 100644 --- a/libfreerdp-core/rts.h +++ b/libfreerdp-core/rts.h @@ -104,6 +104,15 @@ struct _rts_pdu_header }; typedef struct _rts_pdu_header RTS_PDU_HEADER; +struct _rts_pdu +{ + RTS_PDU_HEADER header; + uint8* content; +}; +typedef struct _rts_pdu RTS_PDU; + +boolean rts_connect(rdpRpc* rpc); + void rts_pdu_header_read(STREAM* s, RTS_PDU_HEADER* header); void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header); @@ -138,7 +147,13 @@ void rts_destination_command_write(STREAM* s, uint32 Destination); void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s); void rts_ping_traffic_sent_notify_command_write(STREAM* s, uint32 PingTrafficSent); -int rts_pdu_recv(rdpRpc* rpc, STREAM* s); +boolean rts_send_CONN_A1_pdu(rdpRpc* rpc); +boolean rts_send_CONN_B1_pdu(rdpRpc* rpc); +boolean rts_send_keep_alive_pdu(rdpRpc* rpc); +boolean rts_send_flow_control_ack_pdu(rdpRpc* rpc); +boolean rts_send_ping_pdu(rdpRpc* rpc); + +int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu); #ifdef WITH_DEBUG_TSG #define WITH_DEBUG_RTS From c3d7d553e7c97c7d19ae6d01fb79c26400fec3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 16:29:49 -0400 Subject: [PATCH 24/47] libfreerdp-core: improve second TSG NTLM authentication phase --- libfreerdp-core/rpc.c | 48 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 7bff866f1..8f4cb1bf3 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -485,14 +485,16 @@ boolean rpc_send_bind_pdu(rdpRpc* rpc) int rpc_recv_bind_ack_pdu(rdpRpc* rpc) { + uint8* p; STREAM* s; - uint16 frag_length; - uint16 auth_length; - STREAM* ntlmssp_stream; + int status; + uint8* pdu; + uint8* auth_data; RPC_PDU_HEADER header; - int pdu_length = 0x8FFF; /* 32KB buffer */ - uint8* pdu = xmalloc(pdu_length); - int status = rpc_out_read(rpc, pdu, pdu_length); + int pdu_length = 0x8FFF; + + pdu = xmalloc(pdu_length); + status = rpc_out_read(rpc, pdu, pdu_length); DEBUG_RPC("TODO: complete NTLM integration"); @@ -501,19 +503,22 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) s = stream_new(0); stream_attach(s, pdu, pdu_length); rpc_pdu_header_read(s, &header); + stream_detach(s); + stream_free(s); - frag_length = header.frag_length; - auth_length = header.auth_length; + printf("frag_length:%d auth_length:%d\n", header.frag_length, header.auth_length); - printf("frag_length:%d auth_length:%d\n", frag_length, auth_length); + auth_data = xmalloc(header.auth_length); + p = (pdu + (header.frag_length - header.auth_length)); + memcpy(auth_data, p, header.auth_length); - ntlmssp_stream = stream_new(0xFFFF); - stream_write(ntlmssp_stream, (pdu + (frag_length - auth_length)), auth_length); - ntlmssp_stream->p = ntlmssp_stream->data; + printf("auth_data: (length = %d)\n", header.auth_length); + freerdp_hexdump(auth_data, header.auth_length); - //ntlmssp_recv(rpc->ntlmssp, ntlmssp_stream); + rpc->ntlm->inputBuffer.pvBuffer = auth_data; + rpc->ntlm->inputBuffer.cbBuffer = header.auth_length; - stream_free(ntlmssp_stream); + ntlm_authenticate(rpc->ntlm); } xfree(pdu); @@ -523,14 +528,13 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) { STREAM* pdu; + STREAM* s = stream_new(0); rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; - STREAM* ntlm_stream = stream_new(0xFFFF); DEBUG_RPC("Sending auth_3 PDU"); - ntlm_authenticate(rpc->ntlm); - ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; - ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer; + s->size = rpc->ntlm->outputBuffer.cbBuffer; + s->p = s->data = rpc->ntlm->outputBuffer.pvBuffer; rpc_auth_3_pdu = xnew(rpcconn_rpc_auth_3_hdr_t); rpc_auth_3_pdu->rpc_vers = 5; @@ -541,8 +545,8 @@ boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) rpc_auth_3_pdu->packed_drep[1] = 0x00; rpc_auth_3_pdu->packed_drep[2] = 0x00; rpc_auth_3_pdu->packed_drep[3] = 0x00; - rpc_auth_3_pdu->frag_length = 28 + ntlm_stream->size; - rpc_auth_3_pdu->auth_length = ntlm_stream->size; + rpc_auth_3_pdu->frag_length = 28 + s->size; + rpc_auth_3_pdu->auth_length = s->size; rpc_auth_3_pdu->call_id = 2; rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; @@ -554,9 +558,9 @@ boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) rpc_auth_3_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ rpc_auth_3_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ rpc_auth_3_pdu->auth_verifier.auth_value = xmalloc(rpc_auth_3_pdu->auth_length); /* credentials; size_is(auth_length) p */ - memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, ntlm_stream->data, rpc_auth_3_pdu->auth_length); + memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, s->data, rpc_auth_3_pdu->auth_length); - stream_free(ntlm_stream); + stream_free(s); pdu = stream_new(rpc_auth_3_pdu->frag_length); From 0b35c71b3477c4289a7d8bc834eb5be959d55995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 20:16:48 -0400 Subject: [PATCH 25/47] libfreerdp-core: complete second TSG NTLM authentication --- libfreerdp-core/rpc.c | 47 +++++++++++++++++++++++++++++++------------ libfreerdp-core/rpc.h | 2 +- libfreerdp-core/tsg.c | 12 +++++------ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 8f4cb1bf3..5284573bc 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -359,14 +359,10 @@ boolean rpc_send_bind_pdu(rdpRpc* rpc) rdpSettings* settings = rpc->settings; STREAM* ntlm_stream = stream_new(0xFFFF); - /* TODO: Set NTLMv2 + DO_NOT_SEAL, DomainName = GatewayName? */ - rpc->ntlm = ntlm_new(); DEBUG_RPC("Sending bind PDU"); - DEBUG_RPC("TODO: complete NTLM integration"); - ntlm_client_init(rpc->ntlm, false, settings->username, settings->domain, settings->password); ntlm_authenticate(rpc->ntlm); @@ -660,15 +656,20 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) return header.frag_length; } -int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) +int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) { int i; - rdpBlob rdpMsg; - int status = -1; + int status; + rdpNtlm* ntlm; + SecBuffer Buffers[2]; + SecBufferDesc Message; + SECURITY_STATUS encrypt_status; rpcconn_request_hdr_t* request_pdu; uint8 auth_pad_length = 16 - ((24 + length + 8 + 16) % 16); + ntlm = rpc->ntlm; + if (auth_pad_length == 16) auth_pad_length = 0; @@ -718,14 +719,34 @@ int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) stream_write(pdu, &request_pdu->auth_verifier.auth_type, 8); - rdpMsg.data = pdu->data; - rdpMsg.length = stream_get_length(pdu); + if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK) + { + printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); + return 0; + } - DEBUG_RPC("TODO: complete NTLM integration"); + Buffers[0].BufferType = SECBUFFER_DATA; /* auth_data */ + Buffers[1].BufferType = SECBUFFER_TOKEN; /* signature */ - //ntlmssp_encrypt_message(rpc->ntlmssp, &rdpMsg, NULL, request_pdu->auth_verifier.auth_value); + Buffers[0].pvBuffer = pdu->data; + Buffers[0].cbBuffer = stream_get_length(pdu); - stream_write(pdu, request_pdu->auth_verifier.auth_value, request_pdu->auth_length); + Buffers[1].cbBuffer = ntlm->ContextSizes.cbMaxSignature; + Buffers[1].pvBuffer = xzalloc(Buffers[1].cbBuffer); + + Message.cBuffers = 2; + Message.ulVersion = SECBUFFER_VERSION; + Message.pBuffers = (PSecBuffer) &Buffers; + + encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, 0); + + if (encrypt_status != SEC_E_OK) + { + printf("EncryptMessage status: 0x%08X\n", encrypt_status); + return 0; + } + + stream_write(pdu, Buffers[1].pvBuffer, Buffers[1].cbBuffer); status = rpc_in_write(rpc, pdu->data, pdu->p - pdu->data); @@ -736,7 +757,7 @@ int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) if (status < 0) { printf("rpc_write(): Error! rpc_in_write returned negative value.\n"); - return status; + return -1; } return length; diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 352953bbc..b5f4301a6 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -676,7 +676,7 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length); int rpc_out_read(rdpRpc* rpc, uint8* data, int length); -int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); +int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); int rpc_read(rdpRpc* rpc, uint8* data, int length); rdpRpc* rpc_new(rdpSettings* settings); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 7c28db3ac..bb5b29198 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -227,7 +227,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateTunnel"); - status = rpc_write(rpc, tsg_packet1, sizeof(tsg_packet1), 1); + status = rpc_tsg_write(rpc, tsg_packet1, sizeof(tsg_packet1), 1); if (status <= 0) { @@ -268,7 +268,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyAuthorizeTunnel"); - status = rpc_write(rpc, tsg_packet2, sizeof(tsg_packet2), 2); + status = rpc_tsg_write(rpc, tsg_packet2, sizeof(tsg_packet2), 2); if (status <= 0) { @@ -298,7 +298,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyMakeTunnelCall"); - status = rpc_write(rpc, tsg_packet3, sizeof(tsg_packet3), 3); + status = rpc_tsg_write(rpc, tsg_packet3, sizeof(tsg_packet3), 3); if (status <= 0) { @@ -335,7 +335,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxyCreateChannel"); - status = rpc_write(rpc, s_p4->data, s_p4->size, 4); + status = rpc_tsg_write(rpc, s_p4->data, s_p4->size, 4); if (status <= 0) { @@ -372,7 +372,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) */ DEBUG_TSG("TsProxySetupReceivePipe"); - status = rpc_write(rpc, tsg_packet5, sizeof(tsg_packet5), 8); + status = rpc_tsg_write(rpc, tsg_packet5, sizeof(tsg_packet5), 8); if (status <= 0) { @@ -411,7 +411,7 @@ int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) memcpy(tsg_pkg + 32 + length, pp, 8); - status = rpc_write(tsg->rpc, tsg_pkg, tsg_length, opnum); + status = rpc_tsg_write(tsg->rpc, tsg_pkg, tsg_length, opnum); xfree(tsg_pkg); stream_free(s); From 60da98cea0c0211837eeab60ec25d9dadedeff8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Apr 2012 21:43:30 -0400 Subject: [PATCH 26/47] libfreerdp-core: start fixing TunnelContext creation --- libfreerdp-core/rpc.c | 9 ++++----- libfreerdp-core/rpc.h | 2 +- libfreerdp-core/rts.c | 2 +- libfreerdp-core/tsg.c | 26 +++++++++++++------------- libfreerdp-core/tsg.h | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 5284573bc..4c586bf2a 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -633,7 +633,7 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) else { /* RTS PDUs are not subject to flow control */ - rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived += header.frag_length; + rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header.frag_length; rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length; } @@ -779,8 +779,7 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) { if (rpc->read_buffer_len > length) { - /* TODO fix read_buffer is too long problem */ - printf("ERROR! RPC Stores data in read_buffer fits not in data on rpc_read.\n"); + printf("rpc_read error: receiving buffer is not large enough\n"); return -1; } @@ -803,7 +802,7 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) { printf("Error! rpc_out_read() returned negative value. BytesSent: %d, BytesReceived: %d\n", rpc->VirtualConnection->DefaultInChannel->BytesSent, - rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived); + rpc->VirtualConnection->DefaultOutChannel->BytesReceived); xfree(rpc_data); return status; @@ -878,7 +877,7 @@ boolean rpc_connect(rdpRpc* rpc) void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* virtual_connection) { virtual_connection->DefaultInChannel->BytesSent = 0; - virtual_connection->DefaultOutChannel->RecipientBytesReceived = 0; + virtual_connection->DefaultOutChannel->BytesReceived = 0; virtual_connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow; virtual_connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow; virtual_connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow; diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index b5f4301a6..bc5ddb904 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -594,7 +594,7 @@ struct rpc_out_channel uint32 ReceiveWindow; uint32 ReceiveWindowSize; uint32 ReceiverAvailableWindow; - uint32 RecipientBytesReceived; + uint32 BytesReceived; uint32 AvailableWindowAdvertised; }; typedef struct rpc_out_channel RpcOutChannel; diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index 618cfa2de..5d47a5ec2 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -505,7 +505,7 @@ boolean rts_send_flow_control_ack_pdu(rdpRpc* rpc) DEBUG_RPC("Sending FlowControlAck RTS PDU"); - BytesReceived = rpc->VirtualConnection->DefaultOutChannel->RecipientBytesReceived; + BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived; AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; ChannelCookie = (uint8*) &(rpc->VirtualConnection->DefaultOutChannelCookie); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index bb5b29198..6c37cec5a 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -245,16 +245,16 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - tsg->tunnelContext = xmalloc(16); - memcpy(tsg->tunnelContext, data + 0x91c, 16); + tsg->TunnelContext = xmalloc(16); + memcpy(tsg->TunnelContext, data + 2300, 16); #ifdef WITH_DEBUG_TSG printf("TSG tunnelContext:\n"); - freerdp_hexdump(tsg->tunnelContext, 16); + freerdp_hexdump(tsg->TunnelContext, 16); printf("\n"); #endif - memcpy(tsg_packet2 + 4, tsg->tunnelContext, 16); + memcpy(tsg_packet2 + 4, tsg->TunnelContext, 16); /** * OpNum = 2 @@ -284,7 +284,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - memcpy(tsg_packet3 + 4, tsg->tunnelContext, 16); + memcpy(tsg_packet3 + 4, tsg->TunnelContext, 16); /** * OpNum = 3 @@ -312,7 +312,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) uint8* dest_addr_unic = (uint8*) freerdp_uniconv_out(tsg_uniconv, hostname, (size_t*) &dest_addr_unic_len); freerdp_uniconv_free(tsg_uniconv); - memcpy(tsg_packet4 + 4, tsg->tunnelContext, 16); + memcpy(tsg_packet4 + 4, tsg->TunnelContext, 16); memcpy(tsg_packet4 + 38, &port, 2); STREAM* s_p4 = stream_new(60 + dest_addr_unic_len + 2); @@ -321,7 +321,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) stream_write_uint32(s_p4, 0x00000000); /* Offset */ stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1);/* ActualCount */ stream_write(s_p4, dest_addr_unic, dest_addr_unic_len); - stream_write_uint16(s_p4,0x0000); /* unicode zero to terminate hostname string */ + stream_write_uint16(s_p4, 0x0000); /* unicode zero to terminate hostname string */ /** * OpNum = 4 @@ -352,16 +352,16 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - tsg->channelContext = xmalloc(16); - memcpy(tsg->channelContext, data + 4, 16); + tsg->ChannelContext = xmalloc(16); + memcpy(tsg->ChannelContext, data + 4, 16); #ifdef WITH_DEBUG_TSG - printf("TSG channelContext:\n"); - freerdp_hexdump(tsg->channelContext, 16); + printf("TSG ChannelContext:\n"); + freerdp_hexdump(tsg->ChannelContext, 16); printf("\n"); #endif - memcpy(tsg_packet5 + 4, tsg->channelContext, 16); + memcpy(tsg_packet5 + 4, tsg->ChannelContext, 16); /** * OpNum = 8 @@ -405,7 +405,7 @@ int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) tsg_pkg = xmalloc(tsg_length); memset(tsg_pkg, 0, 4); - memcpy(tsg_pkg + 4, tsg->channelContext, 16); + memcpy(tsg_pkg + 4, tsg->ChannelContext, 16); memcpy(tsg_pkg + 20, s->data, 12); memcpy(tsg_pkg + 32, data, length); diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 76b9f9512..396787ec1 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -37,8 +37,8 @@ typedef struct rdp_tsg rdpTsg; struct rdp_tsg { rdpRpc* rpc; - uint8* tunnelContext; - uint8* channelContext; + uint8* TunnelContext; + uint8* ChannelContext; rdpSettings* settings; rdpTransport* transport; }; From 351fb11521ef2fc176098a2c1404f50c6d6ff681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Apr 2012 15:10:18 -0400 Subject: [PATCH 27/47] libfreerdp-core: fix signing of messages with TSG --- libfreerdp-core/rpc.c | 4 +++- libfreerdp-core/rpc.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 4c586bf2a..7f0c1ba81 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -738,7 +738,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, 0); + encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->send_seq_num++); if (encrypt_status != SEC_E_OK) { @@ -952,6 +952,8 @@ rdpRpc* rpc_new(rdpSettings* settings) rpc->ReceiveWindow = 0x00010000; rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); + rpc->send_seq_num = 0; + rpc->settings = settings; rpc->ntlm = ntlm_new(); diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index bc5ddb904..735c4ddcc 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -651,6 +651,8 @@ struct rdp_rpc RpcVirtualConnection* VirtualConnection; + int send_seq_num; + uint32 call_id; uint32 pipe_call_id; }; From a8580e0f4b54c0037941e2172fe6145bc8d029ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Apr 2012 16:33:18 -0400 Subject: [PATCH 28/47] libfreerdp-core: refactoring of NTLM over HTTP authentication --- libfreerdp-core/rpc.c | 253 ++++++++++++++++++++---------------- libfreerdp-core/rpc.h | 39 +++--- libfreerdp-core/rts.c | 4 +- libfreerdp-core/transport.c | 3 +- libfreerdp-core/tsg.c | 44 ++++--- libfreerdp-core/tsg.h | 2 +- 6 files changed, 191 insertions(+), 154 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 7f0c1ba81..8032e3a12 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -29,18 +29,6 @@ #include "rpc.h" -#define HTTP_STREAM_SIZE 0xFFFF - -boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out) -{ - rpc->tcp_in = tcp_in; - rpc->tcp_out = tcp_out; - rpc->tls_in = tls_in; - rpc->tls_out = tls_out; - - return true; -} - #define NTLM_PACKAGE_NAME _T("NTLM") boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password) @@ -181,123 +169,135 @@ void ntlm_free(rdpNtlm* ntlm) } } -STREAM* rpc_ntlm_http_data(rdpRpc* rpc, char* command, SecBuffer* ntlm_token, uint8* content, int length) +STREAM* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_length, TSG_CHANNEL channel) { STREAM* s; char* base64_ntlm_token; HttpContext* http_context; HttpRequest* http_request; + http_request = http_request_new(); 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; - else - http_context = rpc->http_out->context; + if (channel == TSG_CHANNEL_IN) + { + http_context = rpc->ntlm_http_in->context; + http_request_set_method(http_request, "RPC_IN_DATA"); + } + else if (channel == TSG_CHANNEL_OUT) + { + http_context = rpc->ntlm_http_out->context; + http_request_set_method(http_request, "RPC_OUT_DATA"); + } - http_request = http_request_new(); - - http_request->ContentLength = length; - - http_request_set_method(http_request, http_context->Method); + http_request->ContentLength = content_length; http_request_set_uri(http_request, http_context->URI); http_request_set_auth_scheme(http_request, "NTLM"); http_request_set_auth_param(http_request, base64_ntlm_token); s = http_request_write(http_context, http_request); + http_request_free(http_request); return s; } -boolean rpc_out_connect_http(rdpRpc* rpc) +boolean rpc_ntlm_http_out_connect(rdpRpc* rpc) { STREAM* s; - HttpResponse* http_response; int ntlm_token_length; - uint8* ntlm_token_data = NULL; - rdpTls* tls_out = rpc->tls_out; - rdpSettings* settings = rpc->settings; - rdpRpcHTTP* http_out = rpc->http_out; - rdpNtlm* http_out_ntlm = http_out->ntlm; + uint8* ntlm_token_data; + HttpResponse* http_response; + rdpNtlm* ntlm = rpc->ntlm_http_out->ntlm; - ntlm_client_init(http_out_ntlm, true, settings->username, settings->domain, settings->password); + ntlm_client_init(ntlm, true, rpc->settings->username, + rpc->settings->domain, rpc->settings->password); - ntlm_authenticate(http_out_ntlm); + ntlm_authenticate(ntlm); - s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 0); + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_OUT); /* Send OUT Channel Request */ DEBUG_RPC("\n%s", s->data); - tls_write_all(tls_out, s->data, s->size); + tls_write_all(rpc->tls_out, s->data, s->size); + stream_free(s); /* Receive OUT Channel Response */ - http_response = http_response_recv(tls_out); + http_response = http_response_recv(rpc->tls_out); + ntlm_token_data = NULL; crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); - http_out_ntlm->inputBuffer.pvBuffer = ntlm_token_data; - http_out_ntlm->inputBuffer.cbBuffer = ntlm_token_length; + ntlm->inputBuffer.pvBuffer = ntlm_token_data; + ntlm->inputBuffer.cbBuffer = ntlm_token_length; - ntlm_authenticate(http_out_ntlm); + ntlm_authenticate(ntlm); - s = rpc_ntlm_http_data(rpc, "RPC_OUT_DATA", &http_out_ntlm->outputBuffer, NULL, 76); + http_response_free(http_response); + + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 76, TSG_CHANNEL_OUT); /* Send OUT Channel Request */ DEBUG_RPC("\n%s", s->data); - tls_write_all(tls_out, s->data, s->size); + tls_write_all(rpc->tls_out, s->data, s->size); + stream_free(s); - /* At this point OUT connection is ready to send CONN/A1 and start with receiving data */ + ntlm_client_uninit(ntlm); + ntlm_free(ntlm); return true; } -boolean rpc_in_connect_http(rdpRpc* rpc) +boolean rpc_ntlm_http_in_connect(rdpRpc* rpc) { - STREAM* http_stream; - HttpResponse* http_response; + STREAM* s; int ntlm_token_length; - uint8* ntlm_token_data = NULL; - rdpTls* tls_in = rpc->tls_in; - rdpSettings* settings = rpc->settings; - rdpRpcHTTP* http_in = rpc->http_in; - rdpNtlm* http_in_ntlm = http_in->ntlm; + uint8* ntlm_token_data; + HttpResponse* http_response; + rdpNtlm* ntlm = rpc->ntlm_http_in->ntlm; - ntlm_client_init(http_in_ntlm, true, settings->username, settings->domain, settings->password); + ntlm_client_init(ntlm, true, rpc->settings->username, + rpc->settings->domain, rpc->settings->password); - ntlm_authenticate(http_in_ntlm); + ntlm_authenticate(ntlm); - http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0); + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_IN); /* Send IN Channel Request */ - DEBUG_RPC("\n%s", http_stream->data); - tls_write_all(tls_in, http_stream->data, http_stream->size); + DEBUG_RPC("\n%s", s->data); + tls_write_all(rpc->tls_in, s->data, s->size); + stream_free(s); /* Receive IN Channel Response */ - http_response = http_response_recv(tls_in); + http_response = http_response_recv(rpc->tls_in); + ntlm_token_data = NULL; crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); - http_in_ntlm->inputBuffer.pvBuffer = ntlm_token_data; - http_in_ntlm->inputBuffer.cbBuffer = ntlm_token_length; + ntlm->inputBuffer.pvBuffer = ntlm_token_data; + ntlm->inputBuffer.cbBuffer = ntlm_token_length; - ntlm_authenticate(http_in_ntlm); + ntlm_authenticate(ntlm); - http_stream = rpc_ntlm_http_data(rpc, "RPC_IN_DATA", &http_in_ntlm->outputBuffer, NULL, 0x40000000); + http_response_free(http_response); + + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0x40000000, TSG_CHANNEL_IN); /* Send IN Channel Request */ - DEBUG_RPC("\n%s", http_stream->data); - tls_write_all(tls_in, http_stream->data, http_stream->size); + DEBUG_RPC("\n%s", s->data); + tls_write_all(rpc->tls_in, s->data, s->size); + stream_free(s); - /* At this point IN connection is ready to send CONN/B1 and start with sending data */ + ntlm_client_uninit(ntlm); + ntlm_free(ntlm); return true; } @@ -320,7 +320,6 @@ void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header) int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { int status; - rdpTls* tls_out = rpc->tls_out; #ifdef WITH_DEBUG_RPC printf("rpc_out_write(): length: %d\n", length); @@ -328,7 +327,7 @@ int rpc_out_write(rdpRpc* rpc, uint8* data, int length) printf("\n"); #endif - status = tls_write_all(tls_out, data, length); + status = tls_write_all(rpc->tls_out, data, length); return status; } @@ -336,7 +335,6 @@ int rpc_out_write(rdpRpc* rpc, uint8* data, int length) int rpc_in_write(rdpRpc* rpc, uint8* data, int length) { int status; - rdpTls* tls_in = rpc->tls_in; #ifdef WITH_DEBUG_RPC printf("rpc_in_write() length: %d\n", length); @@ -344,7 +342,7 @@ int rpc_in_write(rdpRpc* rpc, uint8* data, int length) printf("\n"); #endif - status = tls_write_all(tls_in, data, length); + status = tls_write_all(rpc->tls_in, data, length); if (status > 0) rpc->VirtualConnection->DefaultInChannel->BytesSent += status; @@ -473,7 +471,6 @@ boolean rpc_send_bind_pdu(rdpRpc* rpc) rpc_in_write(rpc, pdu->data, pdu->size); - /* TODO there is some allocated memory */ xfree(bind_pdu); return true; @@ -575,17 +572,6 @@ boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) return true; } -int rpc_out_read_http_header(rdpRpc* rpc) -{ - int status = 0; - HttpResponse* http_response; - rdpTls* tls_out = rpc->tls_out; - - http_response = http_response_recv(tls_out); - - return status; -} - int rpc_out_read(rdpRpc* rpc, uint8* data, int length) { STREAM* s; @@ -593,14 +579,13 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) uint8* pdu; int content_length; RPC_PDU_HEADER header; - rdpTls* tls_out = rpc->tls_out; if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */ rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */ pdu = xmalloc(0xFFFF); - status = tls_read(tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */ + status = tls_read(rpc->tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */ if (status <= 0) { @@ -617,7 +602,7 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length) stream_free(s); content_length = header.frag_length - 16; - status = tls_read(tls_out, pdu + 16, content_length); + status = tls_read(rpc->tls_out, pdu + 16, content_length); if (status < 0) { @@ -756,7 +741,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) if (status < 0) { - printf("rpc_write(): Error! rpc_in_write returned negative value.\n"); + printf("rpc_write(): Error! rpc_tsg_write returned negative value.\n"); return -1; } @@ -847,6 +832,9 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) boolean rpc_connect(rdpRpc* rpc) { + rpc->tls_in = rpc->transport->tls_in; + rpc->tls_out = rpc->transport->tls_out; + if (!rts_connect(rpc)) { printf("rts_connect error!\n"); @@ -909,40 +897,74 @@ void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection } } -rdpRpc* rpc_new(rdpSettings* settings) +rdpNtlmHttp* ntlm_http_new() +{ + rdpNtlmHttp* ntlm_http; + + ntlm_http = xnew(rdpNtlmHttp); + + if (ntlm_http != NULL) + { + ntlm_http->ntlm = ntlm_new(); + ntlm_http->context = http_context_new(); + } + + return ntlm_http; +} + +void rpc_ntlm_http_init_channel(rdpRpc* rpc, rdpNtlmHttp* ntlm_http, TSG_CHANNEL channel) +{ + if (channel == TSG_CHANNEL_IN) + http_context_set_method(ntlm_http->context, "RPC_IN_DATA"); + else if (channel == TSG_CHANNEL_OUT) + http_context_set_method(ntlm_http->context, "RPC_OUT_DATA"); + + http_context_set_uri(ntlm_http->context, "/rpc/rpcproxy.dll?localhost:3388"); + http_context_set_accept(ntlm_http->context, "application/rpc"); + http_context_set_cache_control(ntlm_http->context, "no-cache"); + http_context_set_connection(ntlm_http->context, "Keep-Alive"); + http_context_set_user_agent(ntlm_http->context, "MSRPC"); + http_context_set_host(ntlm_http->context, rpc->settings->tsg_hostname); + + if (channel == TSG_CHANNEL_IN) + { + http_context_set_pragma(ntlm_http->context, + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); + } + else if (channel == TSG_CHANNEL_OUT) + { + http_context_set_pragma(ntlm_http->context, + "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729" ", " + "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624"); + } +} + +void ntlm_http_free(rdpNtlmHttp* ntlm_http) +{ + if (ntlm_http != NULL) + { + ntlm_free(ntlm_http->ntlm); + http_context_free(ntlm_http->context); + } +} + +rdpRpc* rpc_new(rdpTransport* transport) { rdpRpc* rpc = (rdpRpc*) xnew(rdpRpc); if (rpc != NULL) { - rpc->http_in = (rdpRpcHTTP*) xnew(rdpRpcHTTP); - rpc->http_out = (rdpRpcHTTP*) xnew(rdpRpcHTTP); + rpc->transport = transport; + rpc->settings = transport->settings; - rpc->http_in->ntlm = ntlm_new(); - rpc->http_out->ntlm = ntlm_new(); + rpc->send_seq_num = 0; + rpc->ntlm = ntlm_new(); - rpc->http_in->context = http_context_new(); - http_context_set_method(rpc->http_in->context, "RPC_IN_DATA"); - http_context_set_uri(rpc->http_in->context, "/rpc/rpcproxy.dll?localhost:3388"); - http_context_set_accept(rpc->http_in->context, "application/rpc"); - http_context_set_cache_control(rpc->http_in->context, "no-cache"); - http_context_set_connection(rpc->http_in->context, "Keep-Alive"); - http_context_set_user_agent(rpc->http_in->context, "MSRPC"); - http_context_set_host(rpc->http_in->context, settings->tsg_hostname); - http_context_set_pragma(rpc->http_in->context, - "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729"); + rpc->ntlm_http_in = ntlm_http_new(); + rpc->ntlm_http_out = ntlm_http_new(); - rpc->http_out->context = http_context_new(); - http_context_set_method(rpc->http_out->context, "RPC_OUT_DATA"); - http_context_set_uri(rpc->http_out->context, "/rpc/rpcproxy.dll?localhost:3388"); - http_context_set_accept(rpc->http_out->context, "application/rpc"); - http_context_set_cache_control(rpc->http_out->context, "no-cache"); - http_context_set_connection(rpc->http_out->context, "Keep-Alive"); - http_context_set_user_agent(rpc->http_out->context, "MSRPC"); - http_context_set_host(rpc->http_out->context, settings->tsg_hostname); - http_context_set_pragma(rpc->http_out->context, - "ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729" ", " - "SessionId=fbd9c34f-397d-471d-a109-1b08cc554624"); + rpc_ntlm_http_init_channel(rpc, rpc->ntlm_http_in, TSG_CHANNEL_IN); + rpc_ntlm_http_init_channel(rpc, rpc->ntlm_http_out, TSG_CHANNEL_OUT); rpc->read_buffer = NULL; rpc->write_buffer = NULL; @@ -952,14 +974,19 @@ rdpRpc* rpc_new(rdpSettings* settings) rpc->ReceiveWindow = 0x00010000; rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); - rpc->send_seq_num = 0; - - rpc->settings = settings; - - rpc->ntlm = ntlm_new(); - rpc->call_id = 0; } return rpc; } + +void rpc_free(rdpRpc* rpc) +{ + if (rpc != NULL) + { + ntlm_http_free(rpc->ntlm_http_in); + ntlm_http_free(rpc->ntlm_http_out); + rpc_client_virtual_connection_free(rpc->VirtualConnection); + xfree(rpc); + } +} diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 735c4ddcc..40acbca4e 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -22,11 +22,12 @@ #define FREERDP_CORE_RPC_H typedef struct rdp_rpc rdpRpc; -typedef struct rdp_rpc_http rdpRpcHTTP; +typedef struct rdp_ntlm_http rdpNtlmHttp; #include "tcp.h" #include "rts.h" #include "http.h" +#include "transport.h" #include #include @@ -551,10 +552,17 @@ struct rdp_ntlm }; typedef struct rdp_ntlm rdpNtlm; -struct rdp_rpc_http +enum _TSG_CHANNEL +{ + TSG_CHANNEL_IN, + TSG_CHANNEL_OUT +}; +typedef enum _TSG_CHANNEL TSG_CHANNEL; + +struct rdp_ntlm_http { - HttpContext* context; rdpNtlm* ntlm; + HttpContext* context; }; /* Ping Originator */ @@ -630,31 +638,30 @@ typedef struct rpc_virtual_connection RpcVirtualConnection; struct rdp_rpc { - rdpTcp* tcp_in; - rdpTcp* tcp_out; rdpTls* tls_in; rdpTls* tls_out; rdpNtlm* ntlm; - rdpRpcHTTP* http_in; - rdpRpcHTTP* http_out; + int send_seq_num; + + rdpNtlmHttp* ntlm_http_in; + rdpNtlmHttp* ntlm_http_out; UNICONV* uniconv; rdpSettings* settings; + rdpTransport* transport; uint8* write_buffer; uint32 write_buffer_len; uint8* read_buffer; uint32 read_buffer_len; + uint32 call_id; + uint32 pipe_call_id; + uint32 ReceiveWindow; RpcVirtualConnection* VirtualConnection; - - int send_seq_num; - - uint32 call_id; - uint32 pipe_call_id; }; boolean ntlm_authenticate(rdpNtlm* ntlm); @@ -665,11 +672,10 @@ void ntlm_client_uninit(rdpNtlm* ntlm); rdpNtlm* ntlm_new(); void ntlm_free(rdpNtlm* ntlm); -boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out); boolean rpc_connect(rdpRpc* rpc); -boolean rpc_out_connect_http(rdpRpc* rpc); -boolean rpc_in_connect_http(rdpRpc* rpc); +boolean rpc_ntlm_http_out_connect(rdpRpc* rpc); +boolean rpc_ntlm_http_in_connect(rdpRpc* rpc); void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header); @@ -681,7 +687,8 @@ int rpc_out_read(rdpRpc* rpc, uint8* data, int length); int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum); int rpc_read(rdpRpc* rpc, uint8* data, int length); -rdpRpc* rpc_new(rdpSettings* settings); +rdpRpc* rpc_new(rdpTransport* transport); +void rpc_free(rdpRpc* rpc); #ifdef WITH_DEBUG_TSG #define WITH_DEBUG_RPC diff --git a/libfreerdp-core/rts.c b/libfreerdp-core/rts.c index 5d47a5ec2..2ad76fcc1 100644 --- a/libfreerdp-core/rts.c +++ b/libfreerdp-core/rts.c @@ -47,7 +47,7 @@ boolean rts_connect(rdpRpc* rpc) RTS_PDU rts_pdu; HttpResponse* http_response; - if (!rpc_out_connect_http(rpc)) + if (!rpc_ntlm_http_out_connect(rpc)) { printf("rpc_out_connect_http error!\n"); return false; @@ -59,7 +59,7 @@ boolean rts_connect(rdpRpc* rpc) return false; } - if (!rpc_in_connect_http(rpc)) + if (!rpc_ntlm_http_in_connect(rpc)) { printf("rpc_in_connect_http error!\n"); return false; diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index a275ffb42..a8451b576 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -134,7 +134,7 @@ boolean transport_connect_nla(rdpTransport* transport) boolean transport_tsg_connect(rdpTransport* transport, const char* hostname, uint16 port) { - rdpTsg* tsg = tsg_new(transport->settings); + rdpTsg* tsg = tsg_new(transport); tsg->transport = transport; transport->tsg = tsg; @@ -498,6 +498,7 @@ void transport_free(rdpTransport* transport) tls_free(transport->tls); tcp_free(transport->tcp); + tsg_free(transport->tsg); xfree(transport); } diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 6c37cec5a..c66a8acae 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -199,13 +199,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) uint32 length; int status = -1; rdpRpc* rpc = tsg->rpc; - rdpTransport* transport = tsg->transport; - - if (!rpc_attach(rpc, transport->tcp_in, transport->tcp_out, transport->tls_in, transport->tls_out)) - { - printf("rpc_attach failed!\n"); - return false; - } if (!rpc_connect(rpc)) { @@ -383,6 +376,15 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return true; } +int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) +{ + int status; + + status = rpc_read(tsg->rpc, data, length); + + return status; +} + uint8 pp[8] = { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -425,27 +427,27 @@ int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) return length; } -int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) -{ - int status; - - status = rpc_read(tsg->rpc, data, length); - - return status; -} - -rdpTsg* tsg_new(rdpSettings* settings) +rdpTsg* tsg_new(rdpTransport* transport) { rdpTsg* tsg; - tsg = (rdpTsg*) xzalloc(sizeof(rdpTsg)); - tsg->settings = settings; - tsg->rpc = rpc_new(settings); + tsg = xnew(rdpTsg); + + if (tsg != NULL) + { + tsg->transport = transport; + tsg->settings = transport->settings; + tsg->rpc = rpc_new(tsg->transport); + } return tsg; } void tsg_free(rdpTsg* tsg) { - + if (tsg != NULL) + { + rpc_free(tsg->rpc); + xfree(tsg); + } } diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 396787ec1..a73cdf552 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -267,7 +267,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port); int tsg_write(rdpTsg* tsg, uint8* data, uint32 length); int tsg_read(rdpTsg* tsg, uint8* data, uint32 length); -rdpTsg* tsg_new(rdpSettings* settings); +rdpTsg* tsg_new(rdpTransport* transport); void tsg_free(rdpTsg* tsg); #ifdef WITH_DEBUG_TSG From d068dcdedc07517c6f84bea480c99df4c61e4a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Apr 2012 20:13:06 -0400 Subject: [PATCH 29/47] libfreerdp-core: refactor tsg_write() --- libfreerdp-core/rpc.c | 7 ++- libfreerdp-core/tsg.c | 133 ++++++++++++++++++++++++++++-------------- libfreerdp-core/tsg.h | 16 +++-- 3 files changed, 106 insertions(+), 50 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 8032e3a12..d32b5590d 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -645,6 +645,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) { int i; int status; + STREAM* pdu; rdpNtlm* ntlm; SecBuffer Buffers[2]; SecBufferDesc Message; @@ -671,7 +672,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) request_pdu->auth_length = 16; request_pdu->call_id = ++rpc->call_id; - /* opnum=8 means [MS-TSGU] TsProxySetupRecievePipe, save call_id for checking pipe responses */ + /* opnum=8 means [MS-TSGU] TsProxySetupReceivePipe, save call_id for checking pipe responses */ if (opnum == 8) rpc->pipe_call_id = rpc->call_id; @@ -680,7 +681,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) request_pdu->p_cont_id = 0x0000; request_pdu->opnum = opnum; request_pdu->stub_data = data; - request_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authentication service */ + request_pdu->auth_verifier.auth_type = 0x0A; /* :01 which authentication service */ request_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ request_pdu->auth_verifier.auth_pad_length = auth_pad_length; /* :01 */ request_pdu->auth_verifier.auth_pad = xmalloc(auth_pad_length); /* align(4); size_is(auth_pad_length) p */ @@ -694,7 +695,7 @@ int rpc_tsg_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum) request_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ request_pdu->auth_verifier.auth_value = xmalloc(request_pdu->auth_length); /* credentials; size_is(auth_length) p */ - STREAM* pdu = stream_new(request_pdu->frag_length); + pdu = stream_new(request_pdu->frag_length); stream_write(pdu, request_pdu, 24); stream_write(pdu, request_pdu->stub_data, request_pdu->alloc_hint); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index c66a8acae..15669e3cc 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -149,6 +149,11 @@ uint8 tsg_packet5[20] = 0x00, 0x00, 0x00, 0x00 }; +void Opnum0NotUsedOnWire(handle_t IDL_handle) +{ + +} + HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId) { @@ -173,6 +178,11 @@ HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, return 0; } +void Opnum5NotUsedOnWire(handle_t IDL_handle) +{ + +} + HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context) { return 0; @@ -183,14 +193,90 @@ HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context) return 0; } -DWORD TsProxySetupReceivePipe(byte pRpcMessage[]) +DWORD TsProxySetupReceivePipe(handle_t IDL_handle, byte pRpcMessage[]) { return 0; } -DWORD TsProxySendToServer(byte pRpcMessage[]) +DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, uint32* lengths) { - return 0; + STREAM* s; + int status; + int length; + rdpTsg* tsg; + byte* buffer1; + byte* buffer2; + byte* buffer3; + uint32 buffer1Length; + uint32 buffer2Length; + uint32 buffer3Length; + uint32 numBuffers = 0; + uint32 totalDataBytes = 0; + + tsg = (rdpTsg*) IDL_handle; + buffer1Length = buffer2Length = buffer3Length = 0; + + if (count > 0) + { + numBuffers++; + buffer1 = &pRpcMessage[0]; + buffer1Length = lengths[0]; + totalDataBytes += lengths[0] + 4; + } + + if (count > 1) + { + numBuffers++; + buffer2 = &pRpcMessage[1]; + buffer2Length = lengths[1]; + totalDataBytes += lengths[1] + 4; + } + + if (count > 2) + { + numBuffers++; + buffer3 = &pRpcMessage[2]; + buffer3Length = lengths[2]; + totalDataBytes += lengths[2] + 4; + } + + s = stream_new(28 + totalDataBytes); + + /* PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE_NR (20 bytes) */ + stream_write_uint32(s, 0); /* ContextType (4 bytes) */ + stream_write(s, tsg->ChannelContext, 16); /* ContextUuid (4 bytes) */ + + stream_write_uint32_be(s, totalDataBytes); /* totalDataBytes (4 bytes) */ + stream_write_uint32_be(s, numBuffers); /* numBuffers (4 bytes) */ + + if (buffer1Length > 0) + stream_write_uint32_be(s, buffer1Length); /* buffer1Length (4 bytes) */ + if (buffer2Length > 0) + stream_write_uint32_be(s, buffer2Length); /* buffer2Length (4 bytes) */ + if (buffer3Length > 0) + stream_write_uint32_be(s, buffer3Length); /* buffer3Length (4 bytes) */ + + if (buffer1Length > 0) + stream_write(s, buffer1, buffer1Length); /* buffer1 (variable) */ + if (buffer2Length > 0) + stream_write(s, buffer2, buffer2Length); /* buffer2 (variable) */ + if (buffer3Length > 0) + stream_write(s, buffer3, buffer3Length); /* buffer3 (variable) */ + + stream_seal(s); + + length = s->size; + status = rpc_tsg_write(tsg->rpc, s->data, s->size, 9); + + stream_free(s); + + if (status <= 0) + { + printf("rpc_tsg_write failed!\n"); + return -1; + } + + return length; } boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) @@ -238,7 +324,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - tsg->TunnelContext = xmalloc(16); memcpy(tsg->TunnelContext, data + 2300, 16); #ifdef WITH_DEBUG_TSG @@ -345,7 +430,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - tsg->ChannelContext = xmalloc(16); memcpy(tsg->ChannelContext, data + 4, 16); #ifdef WITH_DEBUG_TSG @@ -385,46 +469,9 @@ int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) return status; } -uint8 pp[8] = -{ - 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - int tsg_write(rdpTsg* tsg, uint8* data, uint32 length) { - STREAM* s; - uint8* tsg_pkg; - int status = -1; - - uint16 opnum = 9; - uint32 tsg_length = length + 16 + 4 + 12 + 8; - uint32 totalDataBytes = length + 4; - - s = stream_new(12); - stream_write_uint32_be(s, totalDataBytes); - stream_write_uint32_be(s, 0x01); - stream_write_uint32_be(s, length); - - tsg_pkg = xmalloc(tsg_length); - memset(tsg_pkg, 0, 4); - memcpy(tsg_pkg + 4, tsg->ChannelContext, 16); - memcpy(tsg_pkg + 20, s->data, 12); - memcpy(tsg_pkg + 32, data, length); - - memcpy(tsg_pkg + 32 + length, pp, 8); - - status = rpc_tsg_write(tsg->rpc, tsg_pkg, tsg_length, opnum); - - xfree(tsg_pkg); - stream_free(s); - - if (status <= 0) - { - printf("rpc_write failed!\n"); - return -1; - } - - return length; + return TsProxySendToServer((handle_t) tsg, data, 1, &length); } rdpTsg* tsg_new(rdpTransport* transport) diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index a73cdf552..425e5d6d6 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -37,12 +37,16 @@ typedef struct rdp_tsg rdpTsg; struct rdp_tsg { rdpRpc* rpc; - uint8* TunnelContext; - uint8* ChannelContext; rdpSettings* settings; rdpTransport* transport; + uint8 TunnelContext[16]; + uint8 ChannelContext[16]; }; +typedef void* I_RPC_HANDLE; +typedef I_RPC_HANDLE RPC_BINDING_HANDLE; +typedef RPC_BINDING_HANDLE handle_t; + typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE; typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE; @@ -242,6 +246,8 @@ typedef struct _TSG_PACKET TSG_PACKET_TYPE_UNION tsgPacket; } TSG_PACKET, *PTSG_PACKET; +void Opnum0NotUsedOnWire(handle_t IDL_handle); + HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId); @@ -254,13 +260,15 @@ HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId); +void Opnum5NotUsedOnWire(handle_t IDL_handle); + HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context); HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context); -DWORD TsProxySetupReceivePipe(byte pRpcMessage[]); +DWORD TsProxySetupReceivePipe(handle_t IDL_handle, byte pRpcMessage[]); -DWORD TsProxySendToServer(byte pRpcMessage[]); +DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, uint32* lengths); boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port); From 0c66c7f5e2a6f743936990f78a86783f2189f9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 24 Apr 2012 02:02:43 -0400 Subject: [PATCH 30/47] libfreerdp-core: cleanup debug output for auth_3 pdu --- libfreerdp-core/rpc.c | 7 ------- libfreerdp-core/tsg.c | 12 +++++++----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index d32b5590d..760b4db4e 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -489,8 +489,6 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) pdu = xmalloc(pdu_length); status = rpc_out_read(rpc, pdu, pdu_length); - DEBUG_RPC("TODO: complete NTLM integration"); - if (status > 0) { s = stream_new(0); @@ -499,15 +497,10 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) stream_detach(s); stream_free(s); - printf("frag_length:%d auth_length:%d\n", header.frag_length, header.auth_length); - auth_data = xmalloc(header.auth_length); p = (pdu + (header.frag_length - header.auth_length)); memcpy(auth_data, p, header.auth_length); - printf("auth_data: (length = %d)\n", header.auth_length); - freerdp_hexdump(auth_data, header.auth_length); - rpc->ntlm->inputBuffer.pvBuffer = auth_data; rpc->ntlm->inputBuffer.cbBuffer = header.auth_length; diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 15669e3cc..a7773a53f 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -284,7 +284,10 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) uint8* data; uint32 length; int status = -1; + UNICONV* tsg_uniconv; rdpRpc* rpc = tsg->rpc; + uint8* dest_addr_unic; + uint32 dest_addr_unic_len; if (!rpc_connect(rpc)) { @@ -324,10 +327,10 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return false; } - memcpy(tsg->TunnelContext, data + 2300, 16); + memcpy(tsg->TunnelContext, data + (status - 24), 16); #ifdef WITH_DEBUG_TSG - printf("TSG tunnelContext:\n"); + printf("TSG TunnelContext:\n"); freerdp_hexdump(tsg->TunnelContext, 16); printf("\n"); #endif @@ -385,9 +388,8 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) } status = -1; - UNICONV* tsg_uniconv = freerdp_uniconv_new(); - uint32 dest_addr_unic_len; - uint8* dest_addr_unic = (uint8*) freerdp_uniconv_out(tsg_uniconv, hostname, (size_t*) &dest_addr_unic_len); + tsg_uniconv = freerdp_uniconv_new(); + dest_addr_unic = (uint8*) freerdp_uniconv_out(tsg_uniconv, hostname, (size_t*) &dest_addr_unic_len); freerdp_uniconv_free(tsg_uniconv); memcpy(tsg_packet4 + 4, tsg->TunnelContext, 16); From 56c1e4889f1112198db8423e71dd7fc06aa7cc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 28 Apr 2012 18:28:10 -0400 Subject: [PATCH 31/47] libfreerdp-core: added NDR annotations to hex dump samples --- libfreerdp-core/CMakeLists.txt | 2 + libfreerdp-core/ndr.c | 86 ++++++++++++ libfreerdp-core/ndr.h | 57 ++++++++ libfreerdp-core/tsg.c | 234 +++++++++++++++++++++++++++++++-- 4 files changed, 371 insertions(+), 8 deletions(-) create mode 100644 libfreerdp-core/ndr.c create mode 100644 libfreerdp-core/ndr.h diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 94542c2f5..3bc768469 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -41,6 +41,8 @@ set(LIBFREERDP_CORE_SRCS rpc.h rts.c rts.h + ndr.c + ndr.h input.c input.h license.c diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c new file mode 100644 index 000000000..e996de023 --- /dev/null +++ b/libfreerdp-core/ndr.c @@ -0,0 +1,86 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Network Data Representation (NDR) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ndr.h" + +/** + * MSRPC NDR Types Technical Overview: + * http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/ + */ + +void ndr_byte() +{ + +} + +void ndr_char() +{ + +} + +void ndr_small() +{ + +} + +void ndr_usmall() +{ + +} + +void ndr_wchar() +{ + +} + +void ndr_short() +{ + +} + +void ndr_ushort() +{ + +} + +void ndr_long() +{ + +} + +void ndr_ulong() +{ + +} + +void ndr_float() +{ + +} + +void ndr_hyper() +{ + +} + +void ndr_double() +{ + +} + diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h new file mode 100644 index 000000000..64848aee8 --- /dev/null +++ b/libfreerdp-core/ndr.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Network Data Representation (NDR) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CORE_NDR_H +#define FREERDP_CORE_NDR_H + +#include "rpc.h" + +#include "config.h" + +#include +#include +#include +#include + +/* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ + +#define FC_BYTE 0x01 +#define FC_CHAR 0x02 +#define FC_SMALL 0x03 +#define FC_USMALL 0x04 +#define FC_WCHAR 0x05 +#define FC_SHORT 0x06 +#define FC_USHORT 0x07 +#define FC_LONG 0x08 +#define FC_ULONG 0x09 +#define FC_FLOAT 0x0A +#define FC_HYPER 0x0B +#define FC_DOUBLE 0x0C +#define FC_ENUM16 0x0D +#define FC_ENUM32 0x0E +#define FC_ERROR_STATUS_T 0x10 +#define FC_INT3264 0xB8 +#define FC_UINT3264 0xB9 + +#define NdrFcShort(s) (byte)(s & 0xFF), (byte)(s >> 8) + +#define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \ + (byte)((s & 0x00FF0000) >> 16), (byte)(s >> 24) + +#endif /* FREERDP_CORE_NDR_H */ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index a7773a53f..47cd477c6 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -29,6 +29,8 @@ #include #include +#include "ndr.h" + #include "tsg.h" /** @@ -82,6 +84,201 @@ uint8 tsg_packet1[108] = 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 */ +/** + * TsProxyCreateTunnelResponse + * + 05 00 02 03 10 00 00 00 50 09 10 00 01 00 00 00 + 14 09 00 00 00 00 00 00 00 00 02 00 + + 50 43 00 00 TSG_PACKET_TYPE_CAPS_RESPONSE + 50 43 00 00 TSG_PACKET_TYPE_CAPS_RESPONSE + Ptr: 04 00 02 00 + flags: 00 00 00 00 + certChainLen: 39 04 00 00 (1081 * 2 = 2162) + certChainDataPtr: 08 00 02 00 + + GUID? + 95 87 a1 e6 51 6e 6e 4f 90 66 49 4f 9b c2 40 ff + 0c 00 02 00 01 00 00 00 01 00 00 00 00 00 00 00 + 01 00 00 00 + + Ptr: 14 00 02 00 + MaxCount: 39 04 00 00 + Offset: 00 00 00 00 + ActualCount: 39 04 00 00 + + end offset = 105 + 2162 = 2267 (0x08DB) + + 2d 00 2d 00 2d 00 2d 00 ....9...-.-.-.-. + 0070 2d 00 42 00 45 00 47 00 49 00 4e 00 20 00 43 00 -.B.E.G.I.N. .C. + 0080 45 00 52 00 54 00 49 00 46 00 49 00 43 00 41 00 E.R.T.I.F.I.C.A. + 0090 54 00 45 00 2d 00 2d 00 2d 00 2d 00 2d 00 0d 00 T.E.-.-.-.-.-... + 00a0 0a 00 4d 00 49 00 49 00 43 00 34 00 6a 00 43 00 ..M.I.I.C.4.j.C. + 00b0 43 00 41 00 63 00 71 00 67 00 41 00 77 00 49 00 C.A.c.q.g.A.w.I. + 00c0 42 00 41 00 67 00 49 00 51 00 4a 00 38 00 4f 00 B.A.g.I.Q.J.8.O. + 00d0 48 00 6a 00 65 00 66 00 37 00 4e 00 34 00 78 00 H.j.e.f.7.N.4.x. + 00e0 43 00 39 00 30 00 36 00 49 00 53 00 33 00 34 00 C.9.0.6.I.S.3.4. + 00f0 75 00 76 00 54 00 41 00 4e 00 42 00 67 00 6b 00 u.v.T.A.N.B.g.k. + 0100 71 00 68 00 6b 00 69 00 47 00 39 00 77 00 30 00 q.h.k.i.G.9.w.0. + 0110 42 00 41 00 51 00 55 00 46 00 41 00 44 00 41 00 B.A.Q.U.F.A.D.A. + 0120 61 00 0d 00 0a 00 4d 00 52 00 67 00 77 00 46 00 a.....M.R.g.w.F. + 0130 67 00 59 00 44 00 56 00 51 00 51 00 44 00 45 00 g.Y.D.V.Q.Q.D.E. + 0140 77 00 39 00 58 00 53 00 55 00 34 00 74 00 4e 00 w.9.X.S.U.4.t.N. + 0150 7a 00 56 00 46 00 52 00 45 00 4e 00 51 00 52 00 z.V.F.R.E.N.Q.R. + 0160 30 00 64 00 4e 00 52 00 7a 00 6b 00 77 00 48 00 0.d.N.R.z.k.w.H. + 0170 68 00 63 00 4e 00 4d 00 54 00 49 00 77 00 4d 00 h.c.N.M.T.I.w.M. + 0180 7a 00 49 00 34 00 4d 00 44 00 4d 00 77 00 4d 00 z.I.4.M.D.M.w.M. + 0190 54 00 45 00 32 00 57 00 68 00 63 00 4e 00 4d 00 T.E.2.W.h.c.N.M. + 01a0 6a 00 49 00 77 00 0d 00 0a 00 4d 00 7a 00 49 00 j.I.w.....M.z.I. + 01b0 33 00 4d 00 44 00 41 00 77 00 4d 00 44 00 41 00 3.M.D.A.w.M.D.A. + 01c0 77 00 57 00 6a 00 41 00 61 00 4d 00 52 00 67 00 w.W.j.A.a.M.R.g. + 01d0 77 00 46 00 67 00 59 00 44 00 56 00 51 00 51 00 w.F.g.Y.D.V.Q.Q. + 01e0 44 00 45 00 77 00 39 00 58 00 53 00 55 00 34 00 D.E.w.9.X.S.U.4. + 01f0 74 00 4e 00 7a 00 56 00 46 00 52 00 45 00 4e 00 t.N.z.V.F.R.E.N. + 0200 51 00 52 00 30 00 64 00 4e 00 52 00 7a 00 6b 00 Q.R.0.d.N.R.z.k. + 0210 77 00 67 00 67 00 45 00 69 00 4d 00 41 00 30 00 w.g.g.E.i.M.A.0. + 0220 47 00 43 00 53 00 71 00 47 00 0d 00 0a 00 53 00 G.C.S.q.G.....S. + 0230 49 00 62 00 33 00 44 00 51 00 45 00 42 00 41 00 I.b.3.D.Q.E.B.A. + 0240 51 00 55 00 41 00 41 00 34 00 49 00 42 00 44 00 Q.U.A.A.4.I.B.D. + 0250 77 00 41 00 77 00 67 00 67 00 45 00 4b 00 41 00 w.A.w.g.g.E.K.A. + 0260 6f 00 49 00 42 00 41 00 51 00 43 00 6e 00 78 00 o.I.B.A.Q.C.n.x. + 0270 55 00 63 00 32 00 68 00 2b 00 4c 00 5a 00 64 00 U.c.2.h.+.L.Z.d. + 0280 42 00 65 00 56 00 61 00 79 00 35 00 52 00 36 00 B.e.V.a.y.5.R.6. + 0290 68 00 70 00 36 00 47 00 31 00 2b 00 75 00 2f 00 h.p.6.G.1.+.u./. + 02a0 59 00 33 00 7a 00 63 00 33 00 33 00 47 00 0d 00 Y.3.z.c.3.3.G... + 02b0 0a 00 66 00 4c 00 62 00 4f 00 53 00 62 00 48 00 ..f.L.b.O.S.b.H. + 02c0 71 00 6d 00 4e 00 31 00 42 00 4e 00 57 00 79 00 q.m.N.1.B.N.W.y. + 02d0 44 00 7a 00 51 00 66 00 5a 00 71 00 30 00 54 00 D.z.Q.f.Z.q.0.T. + 02e0 35 00 30 00 4b 00 70 00 54 00 61 00 49 00 71 00 5.0.K.p.T.a.I.q. + 02f0 65 00 33 00 58 00 65 00 51 00 4f 00 45 00 63 00 e.3.X.e.Q.O.E.c. + 0300 42 00 33 00 4b 00 78 00 56 00 6a 00 78 00 46 00 B.3.K.x.V.j.x.F. + 0310 46 00 75 00 47 00 67 00 6d 00 57 00 4d 00 55 00 F.u.G.g.m.W.M.U. + 0320 6d 00 7a 00 37 00 79 00 77 00 49 00 49 00 75 00 m.z.7.y.w.I.I.u. + 0330 38 00 0d 00 0a 00 33 00 52 00 56 00 44 00 39 00 8.....3.R.V.D.9. + 0340 36 00 73 00 42 00 30 00 6b 00 31 00 6a 00 37 00 6.s.B.0.k.1.j.7. + 0350 70 00 30 00 4d 00 54 00 6f 00 4a 00 6a 00 71 00 p.0.M.T.o.J.j.q. + 0360 4a 00 45 00 78 00 51 00 56 00 6d 00 48 00 44 00 J.E.x.Q.V.m.H.D. + 0370 72 00 56 00 46 00 2f 00 63 00 4f 00 77 00 6a 00 r.V.F./.c.O.w.j. + 0380 35 00 59 00 69 00 35 00 42 00 33 00 47 00 57 00 5.Y.i.5.B.3.G.W. + 0390 38 00 65 00 65 00 37 00 5a 00 45 00 52 00 30 00 8.e.e.7.Z.E.R.0. + 03a0 76 00 63 00 62 00 4f 00 34 00 59 00 70 00 4c 00 v.c.b.O.4.Y.p.L. + 03b0 64 00 58 00 41 00 0d 00 0a 00 65 00 6f 00 6f 00 d.X.A.....e.o.o. + 03c0 62 00 48 00 6f 00 37 00 7a 00 73 00 65 00 59 00 b.H.o.7.z.s.e.Y. + 03d0 57 00 31 00 37 00 72 00 54 00 4b 00 79 00 73 00 W.1.7.r.T.K.y.s. + 03e0 65 00 59 00 52 00 69 00 6a 00 32 00 6a 00 76 00 e.Y.R.i.j.2.j.v. + 03f0 63 00 6e 00 75 00 6f 00 52 00 72 00 4a 00 48 00 c.n.u.o.R.r.J.H. + 0400 58 00 78 00 36 00 41 00 44 00 64 00 6f 00 57 00 X.x.6.A.D.d.o.W. + 0410 37 00 58 00 4e 00 69 00 39 00 59 00 75 00 55 00 7.X.N.i.9.Y.u.U. + 0420 4a 00 46 00 35 00 6b 00 51 00 46 00 34 00 64 00 J.F.5.k.Q.F.4.d. + 0430 6b 00 73 00 6c 00 5a 00 72 00 0d 00 0a 00 49 00 k.s.l.Z.r.....I. + 0440 44 00 50 00 50 00 6b 00 30 00 68 00 44 00 78 00 D.P.P.k.0.h.D.x. + 0450 6d 00 61 00 49 00 6c 00 5a 00 6a 00 47 00 6a 00 m.a.I.l.Z.j.G.j. + 0460 70 00 55 00 65 00 69 00 47 00 50 00 2b 00 57 00 p.U.e.i.G.P.+.W. + 0470 46 00 68 00 72 00 4d 00 6d 00 6f 00 6b 00 6f 00 F.h.r.M.m.o.k.o. + 0480 46 00 78 00 7a 00 2f 00 70 00 7a 00 61 00 38 00 F.x.z./.p.z.a.8. + 0490 5a 00 4c 00 50 00 4f 00 4a 00 64 00 51 00 76 00 Z.L.P.O.J.d.Q.v. + 04a0 6c 00 31 00 52 00 78 00 34 00 61 00 6e 00 64 00 l.1.R.x.4.a.n.d. + 04b0 43 00 38 00 4d 00 79 00 59 00 47 00 2b 00 0d 00 C.8.M.y.Y.G.+... + 04c0 0a 00 50 00 57 00 62 00 74 00 62 00 44 00 43 00 ..P.W.b.t.b.D.C. + 04d0 31 00 33 00 41 00 71 00 2f 00 44 00 4d 00 4c 00 1.3.A.q./.D.M.L. + 04e0 49 00 56 00 6b 00 6c 00 41 00 65 00 4e 00 6f 00 I.V.k.l.A.e.N.o. + 04f0 78 00 32 00 43 00 61 00 4a 00 65 00 67 00 30 00 x.2.C.a.J.e.g.0. + 0500 56 00 2b 00 48 00 6d 00 46 00 6b 00 70 00 59 00 V.+.H.m.F.k.p.Y. + 0510 68 00 75 00 34 00 6f 00 33 00 6b 00 38 00 6e 00 h.u.4.o.3.k.8.n. + 0520 58 00 5a 00 37 00 7a 00 35 00 41 00 67 00 4d 00 X.Z.7.z.5.A.g.M. + 0530 42 00 41 00 41 00 47 00 6a 00 4a 00 44 00 41 00 B.A.A.G.j.J.D.A. + 0540 69 00 0d 00 0a 00 4d 00 41 00 73 00 47 00 41 00 i.....M.A.s.G.A. + 0550 31 00 55 00 64 00 44 00 77 00 51 00 45 00 41 00 1.U.d.D.w.Q.E.A. + 0560 77 00 49 00 45 00 4d 00 44 00 41 00 54 00 42 00 w.I.E.M.D.A.T.B. + 0570 67 00 4e 00 56 00 48 00 53 00 55 00 45 00 44 00 g.N.V.H.S.U.E.D. + 0580 44 00 41 00 4b 00 42 00 67 00 67 00 72 00 42 00 D.A.K.B.g.g.r.B. + 0590 67 00 45 00 46 00 42 00 51 00 63 00 44 00 41 00 g.E.F.B.Q.c.D.A. + 05a0 54 00 41 00 4e 00 42 00 67 00 6b 00 71 00 68 00 T.A.N.B.g.k.q.h. + 05b0 6b 00 69 00 47 00 39 00 77 00 30 00 42 00 41 00 k.i.G.9.w.0.B.A. + 05c0 51 00 55 00 46 00 0d 00 0a 00 41 00 41 00 4f 00 Q.U.F.....A.A.O. + 05d0 43 00 41 00 51 00 45 00 41 00 52 00 33 00 74 00 C.A.Q.E.A.R.3.t. + 05e0 67 00 2f 00 6e 00 41 00 69 00 73 00 41 00 46 00 g./.n.A.i.s.A.F. + 05f0 42 00 50 00 66 00 5a 00 42 00 68 00 5a 00 31 00 B.P.f.Z.B.h.Z.1. + 0600 71 00 55 00 53 00 74 00 55 00 52 00 32 00 5a 00 q.U.S.t.U.R.2.Z. + 0610 32 00 5a 00 6a 00 55 00 49 00 42 00 70 00 64 00 2.Z.j.U.I.B.p.d. + 0620 68 00 5a 00 4e 00 32 00 64 00 50 00 6b 00 6f 00 h.Z.N.2.d.P.k.o. + 0630 4d 00 6c 00 32 00 4b 00 4f 00 6b 00 66 00 4d 00 M.l.2.K.O.k.f.M. + 0640 4e 00 6d 00 45 00 44 00 45 00 0d 00 0a 00 68 00 N.m.E.D.E.....h. + 0650 72 00 6e 00 56 00 74 00 71 00 54 00 79 00 65 00 r.n.V.t.q.T.y.e. + 0660 50 00 32 00 4e 00 52 00 71 00 78 00 67 00 48 00 P.2.N.R.q.x.g.H. + 0670 46 00 2b 00 48 00 2f 00 6e 00 4f 00 78 00 37 00 F.+.H./.n.O.x.7. + 0680 78 00 6d 00 66 00 49 00 72 00 4c 00 31 00 77 00 x.m.f.I.r.L.1.w. + 0690 45 00 6a 00 63 00 37 00 41 00 50 00 6c 00 37 00 E.j.c.7.A.P.l.7. + 06a0 4b 00 61 00 39 00 4b 00 6a 00 63 00 65 00 6f 00 K.a.9.K.j.c.e.o. + 06b0 4f 00 4f 00 6f 00 68 00 31 00 32 00 6c 00 2f 00 O.O.o.h.1.2.l./. + 06c0 39 00 48 00 53 00 70 00 38 00 30 00 37 00 0d 00 9.H.S.p.8.0.7... + 06d0 0a 00 4f 00 57 00 4d 00 69 00 48 00 41 00 4a 00 ..O.W.M.i.H.A.J. + 06e0 6e 00 66 00 47 00 32 00 46 00 46 00 37 00 6e 00 n.f.G.2.F.F.7.n. + 06f0 51 00 61 00 74 00 63 00 35 00 4e 00 53 00 42 00 Q.a.t.c.5.N.S.B. + 0700 38 00 4e 00 75 00 4f 00 5a 00 67 00 64 00 62 00 8.N.u.O.Z.g.d.b. + 0710 67 00 51 00 2b 00 43 00 42 00 62 00 39 00 76 00 g.Q.+.C.B.b.9.v. + 0720 2b 00 4d 00 56 00 55 00 33 00 43 00 67 00 39 00 +.M.V.U.3.C.g.9. + 0730 4c 00 57 00 65 00 54 00 53 00 2b 00 51 00 78 00 L.W.e.T.S.+.Q.x. + 0740 79 00 59 00 6c 00 37 00 4f 00 30 00 4c 00 43 00 y.Y.l.7.O.0.L.C. + 0750 4d 00 0d 00 0a 00 76 00 45 00 37 00 77 00 4a 00 M.....v.E.7.w.J. + 0760 58 00 53 00 70 00 70 00 4a 00 4c 00 42 00 6b 00 X.S.p.p.J.L.B.k. + 0770 69 00 52 00 72 00 63 00 73 00 51 00 6e 00 34 00 i.R.r.c.s.Q.n.4. + 0780 61 00 39 00 62 00 64 00 67 00 56 00 67 00 6b 00 a.9.b.d.g.V.g.k. + 0790 57 00 32 00 78 00 70 00 7a 00 56 00 4e 00 6d 00 W.2.x.p.z.V.N.m. + 07a0 6e 00 62 00 42 00 35 00 73 00 49 00 49 00 38 00 n.b.B.5.s.I.I.8. + 07b0 35 00 75 00 7a 00 37 00 78 00 76 00 46 00 47 00 5.u.z.7.x.v.F.G. + 07c0 50 00 47 00 65 00 70 00 4c 00 55 00 55 00 55 00 P.G.e.p.L.U.U.U. + 07d0 76 00 66 00 66 00 0d 00 0a 00 36 00 76 00 68 00 v.f.f.....6.v.h. + 07e0 56 00 46 00 5a 00 76 00 62 00 53 00 47 00 73 00 V.F.Z.v.b.S.G.s. + 07f0 77 00 6f 00 72 00 32 00 5a 00 6c 00 54 00 6c 00 w.o.r.2.Z.l.T.l. + 0800 79 00 57 00 70 00 79 00 67 00 5a 00 67 00 71 00 y.W.p.y.g.Z.g.q. + 0810 49 00 46 00 56 00 6f 00 73 00 43 00 4f 00 33 00 I.F.V.o.s.C.O.3. + 0820 34 00 39 00 53 00 65 00 2b 00 55 00 45 00 72 00 4.9.S.e.+.U.E.r. + 0830 72 00 54 00 48 00 46 00 7a 00 71 00 38 00 63 00 r.T.H.F.z.q.8.c. + 0840 76 00 7a 00 4b 00 76 00 63 00 6b 00 4f 00 75 00 v.z.K.v.c.k.O.u. + 0850 4f 00 6b 00 42 00 72 00 42 00 0d 00 0a 00 6c 00 O.k.B.r.B.....l. + 0860 69 00 79 00 4e 00 32 00 47 00 42 00 41 00 6f 00 i.y.N.2.G.B.A.o. + 0870 50 00 45 00 67 00 79 00 4d 00 48 00 41 00 35 00 P.E.g.y.M.H.A.5. + 0880 53 00 78 00 39 00 5a 00 39 00 37 00 35 00 75 00 S.x.9.Z.9.7.5.u. + 0890 6e 00 7a 00 50 00 74 00 77 00 3d 00 3d 00 0d 00 n.z.P.t.w.=.=... + 08a0 0a 00 2d 00 2d 00 2d 00 2d 00 2d 00 45 00 4e 00 ..-.-.-.-.-.E.N. + 08b0 44 00 20 00 43 00 45 00 52 00 54 00 49 00 46 00 D. .C.E.R.T.I.F. + 08c0 49 00 43 00 41 00 54 00 45 00 2d 00 2d 00 2d 00 I.C.A.T.E.-.-.-. + 08d0 2d 00 2d 00 0d 00 0a 00 00 00 + + 00 00 alignment pad? + + 52 54 componentId + 43 56 packetId (TSG_PACKET_TYPE_VERSIONCAPS) + TsgCapsPtr: 10 00 02 00 + NumCapabilities: 01 00 00 00 + MajorVersion: 01 00 + MinorVersion: 01 00 + quarantineCapabilities: 01 00 + pad: 00 00 + NumCapabilitiesConf: + MaxCount: 01 00 00 00 + + tsgCaps: 01 00 00 00 (TSG_CAPABILITY_TYPE_NAP) + SwitchValue: 01 00 00 00 (TSG_CAPABILITY_TYPE_NAP) + capabilities: 1f 00 00 00 = + TSG_NAP_CAPABILITY_QUAR_SOH | + TSG_NAP_CAPABILITY_IDLE_TIMEOUT | + TSG_MESSAGING_CAP_CONSENT_SIGN | + TSG_MESSAGING_CAP_SERVICE_MSG | + TSG_MESSAGING_CAP_REAUTH + + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? + + TunnelContext: + ContextType: 00 00 00 00 + ContextUuid: 81 1d 32 9f 3f ff 8d 41 ae 54 ba e4 7b b7 ef 43 + + 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? + 00 00 00 00 0a 05 0c 00 00 00 00 00 01 00 00 00 + 9d 13 89 41 2e 85 76 3f 00 00 00 00 + */ + uint8 tsg_packet2[112] = { 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, @@ -96,15 +293,36 @@ uint8 tsg_packet2[112] = /** TsProxyAuthorizeTunnel - 0x00, 0x00, 0x00, 0x00, 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, 0x8D, 0x99, 0x29, 0x30, - 0x53, 0x6C, 0x04, 0x33, 0x52, 0x51, 0x00, 0x00, + TunnelContext: + ContextType: 0x00, 0x00, 0x00, 0x00, + ContextUuid: 0x6A, 0x78, 0xE9, 0xAB, 0x02, 0x90, 0x1C, 0x44, + 0x8D, 0x99, 0x29, 0x30, 0x53, 0x6C, 0x04, 0x33, - 0x52, 0x51, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, - 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + TsgPacket: + PacketId: 0x52, 0x51, 0x00, 0x00, + SwitchValue: 0x52, 0x51, 0x00, 0x00, + + PacketQuarRequestPtr: 0x00, 0x00, 0x02, 0x00, + PacketQuarRequest: + Flags: 0x00, 0x00, 0x00, 0x00, + MachineNamePtr: 0x04, 0x00, 0x02, 0x00, + NameLength: 0x15, 0x00, 0x00, 0x00, + DataPtr: 0x08, 0x00, 0x02, 0x00, + DataLen: 0x00, 0x00, 0x00, 0x00, + MachineName: + MaxCount: 0x15, 0x00, 0x00, 0x00, (21 elements) + Offset: 0x00, 0x00, 0x00, 0x00, + ActualCount: 0x15, 0x00, 0x00, 0x00, (21 elements) + Array: 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x2D, 0x00, + 0x4E, 0x00, 0x48, 0x00, 0x35, 0x00, 0x37, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x53, 0x00, + 0x4F, 0x00, 0x44, 0x00, 0x2E, 0x00, 0x6C, 0x00, + 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6C, 0x00, + 0x00, 0x00, + + DataLenConf: + MaxCount: 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 */ uint8 tsg_packet3[40] = From d615aa44da44fd4ab412ef2d7ffa919c5322d1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 28 Apr 2012 20:48:26 -0400 Subject: [PATCH 32/47] libfreerdp-core: added TSGU MIDL generated code with structure definitions --- libfreerdp-core/ndr.c | 62 +- libfreerdp-core/ndr.h | 198 +++++++ libfreerdp-core/tsg.c | 1246 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 1454 insertions(+), 52 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index e996de023..ed8c627f3 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -17,6 +17,8 @@ * limitations under the License. */ +#include + #include "ndr.h" /** @@ -24,63 +26,21 @@ * http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/ */ -void ndr_byte() +CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...) { + CLIENT_CALL_RETURN client_call_return; + client_call_return.Pointer = NULL; + + return client_call_return; } -void ndr_char() +void* MIDL_user_allocate(size_t cBytes) { - + return (xmalloc(cBytes)); } -void ndr_small() +void MIDL_user_free(void* p) { - + xfree(p); } - -void ndr_usmall() -{ - -} - -void ndr_wchar() -{ - -} - -void ndr_short() -{ - -} - -void ndr_ushort() -{ - -} - -void ndr_long() -{ - -} - -void ndr_ulong() -{ - -} - -void ndr_float() -{ - -} - -void ndr_hyper() -{ - -} - -void ndr_double() -{ - -} - diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index 64848aee8..0989dfb2a 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -29,6 +29,199 @@ #include #include +#define __RPC_WIN32__ 1 +#define TARGET_IS_NT50_OR_LATER 1 + +typedef union _CLIENT_CALL_RETURN +{ + void* Pointer; + LONG_PTR Simple; +} CLIENT_CALL_RETURN; + +typedef void* RPC_IF_HANDLE; + +typedef struct _RPC_VERSION +{ + unsigned short MajorVersion; + unsigned short MinorVersion; +} RPC_VERSION; + +typedef struct _RPC_SYNTAX_IDENTIFIER +{ + GUID SyntaxGUID; + RPC_VERSION SyntaxVersion; +} RPC_SYNTAX_IDENTIFIER, PRPC_SYNTAX_IDENTIFIER; + +#define RPC_MGR_EPV void + +typedef struct _RPC_MESSAGE +{ + RPC_BINDING_HANDLE Handle; + unsigned long DataRepresentation; + void* Buffer; + unsigned int BufferLength; + unsigned int ProcNum; + PRPC_SYNTAX_IDENTIFIER TransferSyntax; + void* RpcInterfaceInformation; + void* ReservedForRuntime; + RPC_MGR_EPV* ManagerEpv; + void* ImportContext; + unsigned long RpcFlags; +} RPC_MESSAGE, *PRPC_MESSAGE; + +typedef void (*RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message); + +typedef struct +{ + unsigned int DispatchTableCount; + RPC_DISPATCH_FUNCTION* DispatchTable; + LONG_PTR Reserved; +} RPC_DISPATCH_TABLE, *PRPC_DISPATCH_TABLE; + +typedef struct _RPC_PROTSEQ_ENDPOINT +{ + unsigned char* RpcProtocolSequence; + unsigned char* Endpoint; +} RPC_PROTSEQ_ENDPOINT, * PRPC_PROTSEQ_ENDPOINT; + +typedef struct _RPC_SERVER_INTERFACE +{ + unsigned int Length; + RPC_SYNTAX_IDENTIFIER InterfaceId; + RPC_SYNTAX_IDENTIFIER TransferSyntax; + PRPC_DISPATCH_TABLE DispatchTable; + unsigned int RpcProtseqEndpointCount; + PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint; + RPC_MGR_EPV* DefaultManagerEpv; + void const* InterpreterInfo; + unsigned int Flags; +} RPC_SERVER_INTERFACE, *PRPC_SERVER_INTERFACE; + +typedef struct _RPC_CLIENT_INTERFACE +{ + unsigned int Length; + RPC_SYNTAX_IDENTIFIER InterfaceId; + RPC_SYNTAX_IDENTIFIER TransferSyntax; + PRPC_DISPATCH_TABLE DispatchTable; + unsigned int RpcProtseqEndpointCount; + PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint; + ULONG_PTR Reserved; + void const* InterpreterInfo; + unsigned int Flags; +} RPC_CLIENT_INTERFACE, *PRPC_CLIENT_INTERFACE; + +typedef void* (*GENERIC_BINDING_ROUTINE)(void*); +typedef void (*GENERIC_UNBIND_ROUTINE)(void*, unsigned char*); + +typedef struct _GENERIC_BINDING_ROUTINE_PAIR +{ + GENERIC_BINDING_ROUTINE pfnBind; + GENERIC_UNBIND_ROUTINE pfnUnbind; +} GENERIC_BINDING_ROUTINE_PAIR, *PGENERIC_BINDING_ROUTINE_PAIR; + +typedef struct __GENERIC_BINDING_INFO +{ + void* pObj; + unsigned int Size; + GENERIC_BINDING_ROUTINE pfnBind; + GENERIC_UNBIND_ROUTINE pfnUnbind; +} GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO; + +typedef void (*NDR_RUNDOWN)(void* context); +typedef void (*NDR_NOTIFY_ROUTINE)(void); + +typedef const unsigned char* PFORMAT_STRING; + +typedef struct _MIDL_STUB_MESSAGE +{ + PRPC_MESSAGE RpcMsg; + unsigned char* Buffer; + unsigned char* BufferStart; + unsigned char* BufferEnd; + unsigned char* BufferMark; + unsigned long BufferLength; + unsigned long MemorySize; + unsigned char* Memory; +} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; + +typedef struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; + +typedef void (*EXPR_EVAL)(struct _MIDL_STUB_MESSAGE*); + +typedef void (*XMIT_HELPER_ROUTINE)(PMIDL_STUB_MESSAGE); + +typedef struct _XMIT_ROUTINE_QUINTUPLE +{ + XMIT_HELPER_ROUTINE pfnTranslateToXmit; + XMIT_HELPER_ROUTINE pfnTranslateFromXmit; + XMIT_HELPER_ROUTINE pfnFreeXmit; + XMIT_HELPER_ROUTINE pfnFreeInst; +} XMIT_ROUTINE_QUINTUPLE, *PXMIT_ROUTINE_QUINTUPLE; + +typedef unsigned long (*USER_MARSHAL_SIZING_ROUTINE)(unsigned long*, unsigned long, void*); +typedef unsigned char* (*USER_MARSHAL_MARSHALLING_ROUTINE)(unsigned long*, unsigned char*, void*); +typedef unsigned char* (*USER_MARSHAL_UNMARSHALLING_ROUTINE)(unsigned long*, unsigned char*, void*); +typedef void (*USER_MARSHAL_FREEING_ROUTINE)(unsigned long*, void*); + +typedef struct _USER_MARSHAL_ROUTINE_QUADRUPLE +{ + USER_MARSHAL_SIZING_ROUTINE pfnBufferSize; + USER_MARSHAL_MARSHALLING_ROUTINE pfnMarshall; + USER_MARSHAL_UNMARSHALLING_ROUTINE pfnUnmarshall; + USER_MARSHAL_FREEING_ROUTINE pfnFree; +} USER_MARSHAL_ROUTINE_QUADRUPLE; + +typedef struct _MALLOC_FREE_STRUCT +{ + void* (*pfnAllocate)(size_t); + void (*pfnFree)(void*); +} MALLOC_FREE_STRUCT; + +typedef struct _COMM_FAULT_OFFSETS +{ + short CommOffset; + short FaultOffset; +} COMM_FAULT_OFFSETS; + +typedef void* NDR_CS_ROUTINES; +typedef void* NDR_EXPR_DESC; + +typedef struct _MIDL_STUB_DESC +{ + void* RpcInterfaceInformation; + void* (*pfnAllocate)(size_t); + void (*pfnFree)(void*); + + union + { + handle_t* pAutoHandle; + handle_t* pPrimitiveHandle; + PGENERIC_BINDING_INFO pGenericBindingInfo; + } IMPLICIT_HANDLE_INFO; + + const NDR_RUNDOWN* apfnNdrRundownRoutines; + const GENERIC_BINDING_ROUTINE_PAIR* aGenericBindingRoutinePairs; + const EXPR_EVAL* apfnExprEval; + const XMIT_ROUTINE_QUINTUPLE* aXmitQuintuple; + const unsigned char* pFormatTypes; + + int fCheckBounds; + unsigned long Version; + MALLOC_FREE_STRUCT* pMallocFreeStruct; + + long MIDLVersion; + const COMM_FAULT_OFFSETS* CommFaultOffsets; + const USER_MARSHAL_ROUTINE_QUADRUPLE* aUserMarshalQuadruple; + + const NDR_NOTIFY_ROUTINE* NotifyRoutineTable; + ULONG_PTR mFlags; + const NDR_CS_ROUTINES* CsRoutineTables; + void* ProxyServerInfo; + const NDR_EXPR_DESC* pExprInfo; +} MIDL_STUB_DESC; + +typedef const MIDL_STUB_DESC *PMIDL_STUB_DESC; + /* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ #define FC_BYTE 0x01 @@ -54,4 +247,9 @@ #define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \ (byte)((s & 0x00FF0000) >> 16), (byte)(s >> 24) +CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); + +void* MIDL_user_allocate(size_t cBytes); +void MIDL_user_free(void* p); + #endif /* FREERDP_CORE_NDR_H */ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 47cd477c6..d570083e4 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -39,6 +39,1243 @@ * RPC NDR Interface Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802752/ */ +/** + * START OF GENERATED CODE + */ + +#define TYPE_FORMAT_STRING_SIZE 833 +#define PROC_FORMAT_STRING_SIZE 449 +#define EXPR_FORMAT_STRING_SIZE 1 +#define TRANSMIT_AS_TABLE_SIZE 0 +#define WIRE_MARSHAL_TABLE_SIZE 0 + +typedef struct _ms2Dtsgu_MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } ms2Dtsgu_MIDL_TYPE_FORMAT_STRING; + +typedef struct _ms2Dtsgu_MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } ms2Dtsgu_MIDL_PROC_FORMAT_STRING; + +typedef struct _ms2Dtsgu_MIDL_EXPR_FORMAT_STRING + { + long Pad; + unsigned char Format[ EXPR_FORMAT_STRING_SIZE ]; + } ms2Dtsgu_MIDL_EXPR_FORMAT_STRING; + + +static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax = +{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}; + +static const ms2Dtsgu_MIDL_TYPE_FORMAT_STRING ms2Dtsgu__MIDL_TypeFormatString; +static const ms2Dtsgu_MIDL_PROC_FORMAT_STRING ms2Dtsgu__MIDL_ProcFormatString; +static const ms2Dtsgu_MIDL_EXPR_FORMAT_STRING ms2Dtsgu__MIDL_ExprFormatString; + +#define GENERIC_BINDING_TABLE_SIZE 0 + +static const RPC_CLIENT_INTERFACE TsProxyRpcInterface___RpcClientInterface = + { + sizeof(RPC_CLIENT_INTERFACE), + {{0x44e265dd,0x7daf,0x42cd,{0x85,0x60,0x3c,0xdb,0x6e,0x7a,0x27,0x29}},{1,3}}, + {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}}, + 0, + 0, + 0, + 0, + 0, + 0x00000000 + }; +RPC_IF_HANDLE TsProxyRpcInterface_v1_3_c_ifspec = (RPC_IF_HANDLE)& TsProxyRpcInterface___RpcClientInterface; + +static const MIDL_STUB_DESC TsProxyRpcInterface_StubDesc; + +static RPC_BINDING_HANDLE TsProxyRpcInterface__MIDL_AutoBindHandle; + + +void Opnum0NotUsedOnWire( + /* [in] */ handle_t IDL_handle) +{ + + NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[0], + ( unsigned char * )&IDL_handle); + +} + + +HRESULT TsProxyCreateTunnel( + /* [ref][in] */ PTSG_PACKET tsgPacket, + /* [ref][out] */ PTSG_PACKET *tsgPacketResponse, + /* [out] */ PTUNNEL_CONTEXT_HANDLE_SERIALIZE *tunnelContext, + /* [out] */ unsigned long *tunnelId) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[28], + ( unsigned char * )&tsgPacket); + return ( HRESULT )_RetVal.Simple; + +} + + +HRESULT TsProxyAuthorizeTunnel( + /* [in] */ PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + /* [ref][in] */ PTSG_PACKET tsgPacket, + /* [ref][out] */ PTSG_PACKET *tsgPacketResponse) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[82], + ( unsigned char * )&tunnelContext); + return ( HRESULT )_RetVal.Simple; + +} + + +HRESULT TsProxyMakeTunnelCall( + /* [in] */ PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + /* [in] */ unsigned long procId, + /* [ref][in] */ PTSG_PACKET tsgPacket, + /* [ref][out] */ PTSG_PACKET *tsgPacketResponse) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[136], + ( unsigned char * )&tunnelContext); + return ( HRESULT )_RetVal.Simple; + +} + + +HRESULT TsProxyCreateChannel( + /* [in] */ PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + /* [ref][in] */ PTSENDPOINTINFO tsEndPointInfo, + /* [out] */ PCHANNEL_CONTEXT_HANDLE_SERIALIZE *channelContext, + /* [out] */ unsigned long *channelId) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[196], + ( unsigned char * )&tunnelContext); + return ( HRESULT )_RetVal.Simple; + +} + + +void Opnum5NotUsedOnWire( + /* [in] */ handle_t IDL_handle) +{ + + NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[256], + ( unsigned char * )&IDL_handle); + +} + + +HRESULT TsProxyCloseChannel( + /* [out][in] */ PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE *context) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[284], + ( unsigned char * )&context); + return ( HRESULT )_RetVal.Simple; + +} + + +HRESULT TsProxyCloseTunnel( + /* [out][in] */ PTUNNEL_CONTEXT_HANDLE_SERIALIZE *context) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[326], + ( unsigned char * )&context); + return ( HRESULT )_RetVal.Simple; + +} + + +DWORD TsProxySetupReceivePipe( + /* [in] */ handle_t IDL_handle, + /* [max_is][in] */ byte pRpcMessage[ ]) +{ + + CLIENT_CALL_RETURN _RetVal; + + _RetVal = NdrClientCall2( + ( PMIDL_STUB_DESC )&TsProxyRpcInterface_StubDesc, + (PFORMAT_STRING) &ms2Dtsgu__MIDL_ProcFormatString.Format[368], + ( unsigned char * )&IDL_handle); + return ( DWORD )_RetVal.Simple; + +} + +static const ms2Dtsgu_MIDL_PROC_FORMAT_STRING ms2Dtsgu__MIDL_ProcFormatString = + { + 0, + { + + /* Procedure Opnum0NotUsedOnWire */ + + 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 2 */ NdrFcLong( 0x0 ), /* 0 */ +/* 6 */ NdrFcShort( 0x0 ), /* 0 */ +/* 8 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */ + 0x0, /* 0 */ +/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 14 */ NdrFcShort( 0x0 ), /* 0 */ +/* 16 */ NdrFcShort( 0x0 ), /* 0 */ +/* 18 */ 0x40, /* Oi2 Flags: has ext, */ + 0x0, /* 0 */ +/* 20 */ 0x8, /* 8 */ + 0x1, /* Ext Flags: new corr desc, */ +/* 22 */ NdrFcShort( 0x0 ), /* 0 */ +/* 24 */ NdrFcShort( 0x0 ), /* 0 */ +/* 26 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Procedure TsProxyCreateTunnel */ + + + /* Parameter IDL_handle */ + +/* 28 */ 0x33, /* FC_AUTO_HANDLE */ + 0x48, /* Old Flags: */ +/* 30 */ NdrFcLong( 0x0 ), /* 0 */ +/* 34 */ NdrFcShort( 0x1 ), /* 1 */ +/* 36 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 38 */ NdrFcShort( 0x0 ), /* 0 */ +/* 40 */ NdrFcShort( 0x5c ), /* 92 */ +/* 42 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ + 0x5, /* 5 */ +/* 44 */ 0x8, /* 8 */ + 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ +/* 46 */ NdrFcShort( 0x1 ), /* 1 */ +/* 48 */ NdrFcShort( 0x1 ), /* 1 */ +/* 50 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter tsgPacket */ + +/* 52 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 54 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 56 */ NdrFcShort( 0x280 ), /* Type Offset=640 */ + + /* Parameter tsgPacketResponse */ + +/* 58 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */ +/* 60 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 62 */ NdrFcShort( 0x28e ), /* Type Offset=654 */ + + /* Parameter tunnelContext */ + +/* 64 */ NdrFcShort( 0x110 ), /* Flags: out, simple ref, */ +/* 66 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 68 */ NdrFcShort( 0x29a ), /* Type Offset=666 */ + + /* Parameter tunnelId */ + +/* 70 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 72 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 74 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 76 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 78 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 80 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxyAuthorizeTunnel */ + +/* 82 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 84 */ NdrFcLong( 0x0 ), /* 0 */ +/* 88 */ NdrFcShort( 0x2 ), /* 2 */ +/* 90 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 92 */ 0x30, /* FC_BIND_CONTEXT */ + 0x40, /* Ctxt flags: in, */ +/* 94 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 96 */ 0x1, /* 1 */ + 0x0, /* 0 */ +/* 98 */ NdrFcShort( 0x24 ), /* 36 */ +/* 100 */ NdrFcShort( 0x8 ), /* 8 */ +/* 102 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ + 0x4, /* 4 */ +/* 104 */ 0x8, /* 8 */ + 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ +/* 106 */ NdrFcShort( 0x1 ), /* 1 */ +/* 108 */ NdrFcShort( 0x1 ), /* 1 */ +/* 110 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter tunnelContext */ + +/* 112 */ NdrFcShort( 0x8 ), /* Flags: in, */ +/* 114 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 116 */ NdrFcShort( 0x2a2 ), /* Type Offset=674 */ + + /* Parameter tsgPacket */ + +/* 118 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 120 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 122 */ NdrFcShort( 0x280 ), /* Type Offset=640 */ + + /* Parameter tsgPacketResponse */ + +/* 124 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */ +/* 126 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 128 */ NdrFcShort( 0x28e ), /* Type Offset=654 */ + + /* Return value */ + +/* 130 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 132 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 134 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxyMakeTunnelCall */ + +/* 136 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 138 */ NdrFcLong( 0x0 ), /* 0 */ +/* 142 */ NdrFcShort( 0x3 ), /* 3 */ +/* 144 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 146 */ 0x30, /* FC_BIND_CONTEXT */ + 0x40, /* Ctxt flags: in, */ +/* 148 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 150 */ 0x1, /* 1 */ + 0x0, /* 0 */ +/* 152 */ NdrFcShort( 0x2c ), /* 44 */ +/* 154 */ NdrFcShort( 0x8 ), /* 8 */ +/* 156 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ + 0x5, /* 5 */ +/* 158 */ 0x8, /* 8 */ + 0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */ +/* 160 */ NdrFcShort( 0x1 ), /* 1 */ +/* 162 */ NdrFcShort( 0x1 ), /* 1 */ +/* 164 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter tunnelContext */ + +/* 166 */ NdrFcShort( 0x8 ), /* Flags: in, */ +/* 168 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 170 */ NdrFcShort( 0x2a2 ), /* Type Offset=674 */ + + /* Parameter procId */ + +/* 172 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 174 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 176 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Parameter tsgPacket */ + +/* 178 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 180 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 182 */ NdrFcShort( 0x280 ), /* Type Offset=640 */ + + /* Parameter tsgPacketResponse */ + +/* 184 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */ +/* 186 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 188 */ NdrFcShort( 0x28e ), /* Type Offset=654 */ + + /* Return value */ + +/* 190 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 192 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 194 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxyCreateChannel */ + +/* 196 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 198 */ NdrFcLong( 0x0 ), /* 0 */ +/* 202 */ NdrFcShort( 0x4 ), /* 4 */ +/* 204 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 206 */ 0x30, /* FC_BIND_CONTEXT */ + 0x40, /* Ctxt flags: in, */ +/* 208 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 210 */ 0x1, /* 1 */ + 0x0, /* 0 */ +/* 212 */ NdrFcShort( 0x24 ), /* 36 */ +/* 214 */ NdrFcShort( 0x5c ), /* 92 */ +/* 216 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x5, /* 5 */ +/* 218 */ 0x8, /* 8 */ + 0x5, /* Ext Flags: new corr desc, srv corr check, */ +/* 220 */ NdrFcShort( 0x0 ), /* 0 */ +/* 222 */ NdrFcShort( 0x1 ), /* 1 */ +/* 224 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter tunnelContext */ + +/* 226 */ NdrFcShort( 0x8 ), /* Flags: in, */ +/* 228 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 230 */ NdrFcShort( 0x2a2 ), /* Type Offset=674 */ + + /* Parameter tsEndPointInfo */ + +/* 232 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 234 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 236 */ NdrFcShort( 0x2fe ), /* Type Offset=766 */ + + /* Parameter channelContext */ + +/* 238 */ NdrFcShort( 0x110 ), /* Flags: out, simple ref, */ +/* 240 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 242 */ NdrFcShort( 0x320 ), /* Type Offset=800 */ + + /* Parameter channelId */ + +/* 244 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 246 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 248 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 250 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 252 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 254 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure Opnum5NotUsedOnWire */ + +/* 256 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 258 */ NdrFcLong( 0x0 ), /* 0 */ +/* 262 */ NdrFcShort( 0x5 ), /* 5 */ +/* 264 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 266 */ 0x32, /* FC_BIND_PRIMITIVE */ + 0x0, /* 0 */ +/* 268 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 270 */ NdrFcShort( 0x0 ), /* 0 */ +/* 272 */ NdrFcShort( 0x0 ), /* 0 */ +/* 274 */ 0x40, /* Oi2 Flags: has ext, */ + 0x0, /* 0 */ +/* 276 */ 0x8, /* 8 */ + 0x1, /* Ext Flags: new corr desc, */ +/* 278 */ NdrFcShort( 0x0 ), /* 0 */ +/* 280 */ NdrFcShort( 0x0 ), /* 0 */ +/* 282 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Procedure TsProxyCloseChannel */ + + + /* Parameter IDL_handle */ + +/* 284 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 286 */ NdrFcLong( 0x0 ), /* 0 */ +/* 290 */ NdrFcShort( 0x6 ), /* 6 */ +/* 292 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 294 */ 0x30, /* FC_BIND_CONTEXT */ + 0xe0, /* Ctxt flags: via ptr, in, out, */ +/* 296 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 298 */ 0x3, /* 3 */ + 0x0, /* 0 */ +/* 300 */ NdrFcShort( 0x38 ), /* 56 */ +/* 302 */ NdrFcShort( 0x40 ), /* 64 */ +/* 304 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 306 */ 0x8, /* 8 */ + 0x1, /* Ext Flags: new corr desc, */ +/* 308 */ NdrFcShort( 0x0 ), /* 0 */ +/* 310 */ NdrFcShort( 0x0 ), /* 0 */ +/* 312 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter context */ + +/* 314 */ NdrFcShort( 0x118 ), /* Flags: in, out, simple ref, */ +/* 316 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 318 */ NdrFcShort( 0x328 ), /* Type Offset=808 */ + + /* Return value */ + +/* 320 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 322 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 324 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxyCloseTunnel */ + +/* 326 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 328 */ NdrFcLong( 0x0 ), /* 0 */ +/* 332 */ NdrFcShort( 0x7 ), /* 7 */ +/* 334 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 336 */ 0x30, /* FC_BIND_CONTEXT */ + 0xe0, /* Ctxt flags: via ptr, in, out, */ +/* 338 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 340 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 342 */ NdrFcShort( 0x38 ), /* 56 */ +/* 344 */ NdrFcShort( 0x40 ), /* 64 */ +/* 346 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 348 */ 0x8, /* 8 */ + 0x1, /* Ext Flags: new corr desc, */ +/* 350 */ NdrFcShort( 0x0 ), /* 0 */ +/* 352 */ NdrFcShort( 0x0 ), /* 0 */ +/* 354 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter context */ + +/* 356 */ NdrFcShort( 0x118 ), /* Flags: in, out, simple ref, */ +/* 358 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 360 */ NdrFcShort( 0x330 ), /* Type Offset=816 */ + + /* Return value */ + +/* 362 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 364 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 366 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxySetupReceivePipe */ + +/* 368 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 370 */ NdrFcLong( 0x0 ), /* 0 */ +/* 374 */ NdrFcShort( 0x8 ), /* 8 */ +/* 376 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 378 */ 0x32, /* FC_BIND_PRIMITIVE */ + 0x0, /* 0 */ +/* 380 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 382 */ NdrFcShort( 0x0 ), /* 0 */ +/* 384 */ NdrFcShort( 0x8 ), /* 8 */ +/* 386 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x2, /* 2 */ +/* 388 */ 0x8, /* 8 */ + 0x5, /* Ext Flags: new corr desc, srv corr check, */ +/* 390 */ NdrFcShort( 0x0 ), /* 0 */ +/* 392 */ NdrFcShort( 0x1 ), /* 1 */ +/* 394 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter IDL_handle */ + +/* 396 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 398 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 400 */ NdrFcShort( 0x334 ), /* Type Offset=820 */ + + /* Parameter pRpcMessage */ + +/* 402 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 404 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 406 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure TsProxySendToServer */ + + + /* Return value */ + +/* 408 */ 0x0, /* 0 */ + 0x48, /* Old Flags: */ +/* 410 */ NdrFcLong( 0x0 ), /* 0 */ +/* 414 */ NdrFcShort( 0x9 ), /* 9 */ +/* 416 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 418 */ 0x32, /* FC_BIND_PRIMITIVE */ + 0x0, /* 0 */ +/* 420 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */ +/* 422 */ NdrFcShort( 0x0 ), /* 0 */ +/* 424 */ NdrFcShort( 0x8 ), /* 8 */ +/* 426 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x2, /* 2 */ +/* 428 */ 0x8, /* 8 */ + 0x5, /* Ext Flags: new corr desc, srv corr check, */ +/* 430 */ NdrFcShort( 0x0 ), /* 0 */ +/* 432 */ NdrFcShort( 0x1 ), /* 1 */ +/* 434 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter IDL_handle */ + +/* 436 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 438 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 440 */ NdrFcShort( 0x334 ), /* Type Offset=820 */ + + /* Parameter pRpcMessage */ + +/* 442 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 444 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 446 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + 0x0 + } + }; + +static const ms2Dtsgu_MIDL_TYPE_FORMAT_STRING ms2Dtsgu__MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ +/* 2 */ + 0x11, 0x0, /* FC_RP */ +/* 4 */ NdrFcShort( 0x27c ), /* Offset= 636 (640) */ +/* 6 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x9, /* FC_ULONG */ +/* 8 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 10 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 12 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 14 */ NdrFcShort( 0x2 ), /* Offset= 2 (16) */ +/* 16 */ NdrFcShort( 0x4 ), /* 4 */ +/* 18 */ NdrFcShort( 0xb ), /* 11 */ +/* 20 */ NdrFcLong( 0x4844 ), /* 18500 */ +/* 24 */ NdrFcShort( 0x40 ), /* Offset= 64 (88) */ +/* 26 */ NdrFcLong( 0x5643 ), /* 22083 */ +/* 30 */ NdrFcShort( 0x46 ), /* Offset= 70 (100) */ +/* 32 */ NdrFcLong( 0x5143 ), /* 20803 */ +/* 36 */ NdrFcShort( 0xa8 ), /* Offset= 168 (204) */ +/* 38 */ NdrFcLong( 0x5152 ), /* 20818 */ +/* 42 */ NdrFcShort( 0xa6 ), /* Offset= 166 (208) */ +/* 44 */ NdrFcLong( 0x5052 ), /* 20562 */ +/* 48 */ NdrFcShort( 0xe8 ), /* Offset= 232 (280) */ +/* 50 */ NdrFcLong( 0x4552 ), /* 17746 */ +/* 54 */ NdrFcShort( 0x122 ), /* Offset= 290 (344) */ +/* 56 */ NdrFcLong( 0x4350 ), /* 17232 */ +/* 60 */ NdrFcShort( 0x160 ), /* Offset= 352 (412) */ +/* 62 */ NdrFcLong( 0x4752 ), /* 18258 */ +/* 66 */ NdrFcShort( 0x8a ), /* Offset= 138 (204) */ +/* 68 */ NdrFcLong( 0x4750 ), /* 18256 */ +/* 72 */ NdrFcShort( 0x1d4 ), /* Offset= 468 (540) */ +/* 74 */ NdrFcLong( 0x4054 ), /* 16468 */ +/* 78 */ NdrFcShort( 0x1d2 ), /* Offset= 466 (544) */ +/* 80 */ NdrFcLong( 0x5250 ), /* 21072 */ +/* 84 */ NdrFcShort( 0x1fc ), /* Offset= 508 (592) */ +/* 86 */ NdrFcShort( 0xffff ), /* Offset= -1 (85) */ +/* 88 */ + 0x12, 0x0, /* FC_UP */ +/* 90 */ NdrFcShort( 0x2 ), /* Offset= 2 (92) */ +/* 92 */ + 0x15, /* FC_STRUCT */ + 0x1, /* 1 */ +/* 94 */ NdrFcShort( 0x4 ), /* 4 */ +/* 96 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 98 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 100 */ + 0x12, 0x0, /* FC_UP */ +/* 102 */ NdrFcShort( 0x4c ), /* Offset= 76 (178) */ +/* 104 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 106 */ NdrFcLong( 0x0 ), /* 0 */ +/* 110 */ NdrFcLong( 0x20 ), /* 32 */ +/* 114 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x9, /* FC_ULONG */ +/* 116 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 118 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 120 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 122 */ NdrFcShort( 0x2 ), /* Offset= 2 (124) */ +/* 124 */ NdrFcShort( 0x4 ), /* 4 */ +/* 126 */ NdrFcShort( 0x1 ), /* 1 */ +/* 128 */ NdrFcLong( 0x1 ), /* 1 */ +/* 132 */ NdrFcShort( 0x4 ), /* Offset= 4 (136) */ +/* 134 */ NdrFcShort( 0xffff ), /* Offset= -1 (133) */ +/* 136 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 138 */ NdrFcShort( 0x4 ), /* 4 */ +/* 140 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 142 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 144 */ NdrFcShort( 0x8 ), /* 8 */ +/* 146 */ NdrFcShort( 0x0 ), /* 0 */ +/* 148 */ NdrFcShort( 0x0 ), /* Offset= 0 (148) */ +/* 150 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 152 */ 0x0, /* 0 */ + NdrFcShort( 0xffd9 ), /* Offset= -39 (114) */ + 0x5b, /* FC_END */ +/* 156 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 158 */ NdrFcShort( 0x0 ), /* 0 */ +/* 160 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 162 */ NdrFcShort( 0x8 ), /* 8 */ +/* 164 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 166 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 170 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 172 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 174 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (142) */ +/* 176 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 178 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 180 */ NdrFcShort( 0x14 ), /* 20 */ +/* 182 */ NdrFcShort( 0x0 ), /* 0 */ +/* 184 */ NdrFcShort( 0x10 ), /* Offset= 16 (200) */ +/* 186 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 188 */ NdrFcShort( 0xffa0 ), /* Offset= -96 (92) */ +/* 190 */ 0x36, /* FC_POINTER */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 192 */ 0x0, /* 0 */ + NdrFcShort( 0xffa7 ), /* Offset= -89 (104) */ + 0x6, /* FC_SHORT */ +/* 196 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 198 */ 0x3e, /* FC_STRUCTPAD2 */ + 0x5b, /* FC_END */ +/* 200 */ + 0x12, 0x0, /* FC_UP */ +/* 202 */ NdrFcShort( 0xffd2 ), /* Offset= -46 (156) */ +/* 204 */ + 0x12, 0x0, /* FC_UP */ +/* 206 */ NdrFcShort( 0xffba ), /* Offset= -70 (136) */ +/* 208 */ + 0x12, 0x0, /* FC_UP */ +/* 210 */ NdrFcShort( 0x2a ), /* Offset= 42 (252) */ +/* 212 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 214 */ NdrFcLong( 0x0 ), /* 0 */ +/* 218 */ NdrFcLong( 0x201 ), /* 513 */ +/* 222 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 224 */ NdrFcLong( 0x0 ), /* 0 */ +/* 228 */ NdrFcLong( 0x1f40 ), /* 8000 */ +/* 232 */ + 0x25, /* FC_C_WSTRING */ + 0x44, /* FC_STRING_SIZED */ +/* 234 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 236 */ NdrFcShort( 0x8 ), /* 8 */ +/* 238 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 240 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 242 */ NdrFcShort( 0x1 ), /* 1 */ +/* 244 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 246 */ NdrFcShort( 0x10 ), /* 16 */ +/* 248 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 250 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 252 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 254 */ NdrFcShort( 0x14 ), /* 20 */ +/* 256 */ NdrFcShort( 0x0 ), /* 0 */ +/* 258 */ NdrFcShort( 0xe ), /* Offset= 14 (272) */ +/* 260 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 262 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 264 */ NdrFcShort( 0xffcc ), /* Offset= -52 (212) */ +/* 266 */ 0x36, /* FC_POINTER */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 268 */ 0x0, /* 0 */ + NdrFcShort( 0xffd1 ), /* Offset= -47 (222) */ + 0x5b, /* FC_END */ +/* 272 */ + 0x12, 0x0, /* FC_UP */ +/* 274 */ NdrFcShort( 0xffd6 ), /* Offset= -42 (232) */ +/* 276 */ + 0x12, 0x0, /* FC_UP */ +/* 278 */ NdrFcShort( 0xffda ), /* Offset= -38 (240) */ +/* 280 */ + 0x12, 0x0, /* FC_UP */ +/* 282 */ NdrFcShort( 0x26 ), /* Offset= 38 (320) */ +/* 284 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 286 */ NdrFcLong( 0x0 ), /* 0 */ +/* 290 */ NdrFcLong( 0x5dc0 ), /* 24000 */ +/* 294 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 296 */ NdrFcShort( 0x20 ), /* 32 */ +/* 298 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 300 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 302 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 304 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 306 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 308 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 310 */ NdrFcShort( 0x1 ), /* 1 */ +/* 312 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 314 */ NdrFcShort( 0xc ), /* 12 */ +/* 316 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 318 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 320 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 322 */ NdrFcShort( 0x30 ), /* 48 */ +/* 324 */ NdrFcShort( 0x0 ), /* 0 */ +/* 326 */ NdrFcShort( 0xe ), /* Offset= 14 (340) */ +/* 328 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 330 */ 0x36, /* FC_POINTER */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 332 */ 0x0, /* 0 */ + NdrFcShort( 0xffcf ), /* Offset= -49 (284) */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 336 */ 0x0, /* 0 */ + NdrFcShort( 0xffd5 ), /* Offset= -43 (294) */ + 0x5b, /* FC_END */ +/* 340 */ + 0x12, 0x0, /* FC_UP */ +/* 342 */ NdrFcShort( 0xffde ), /* Offset= -34 (308) */ +/* 344 */ + 0x12, 0x0, /* FC_UP */ +/* 346 */ NdrFcShort( 0x26 ), /* Offset= 38 (384) */ +/* 348 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 350 */ NdrFcLong( 0x0 ), /* 0 */ +/* 354 */ NdrFcLong( 0x5dc0 ), /* 24000 */ +/* 358 */ + 0x1d, /* FC_SMFARRAY */ + 0x0, /* 0 */ +/* 360 */ NdrFcShort( 0x8 ), /* 8 */ +/* 362 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 364 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 366 */ NdrFcShort( 0x10 ), /* 16 */ +/* 368 */ 0x8, /* FC_LONG */ + 0x6, /* FC_SHORT */ +/* 370 */ 0x6, /* FC_SHORT */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 372 */ 0x0, /* 0 */ + NdrFcShort( 0xfff1 ), /* Offset= -15 (358) */ + 0x5b, /* FC_END */ +/* 376 */ + 0x25, /* FC_C_WSTRING */ + 0x44, /* FC_STRING_SIZED */ +/* 378 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 380 */ NdrFcShort( 0x4 ), /* 4 */ +/* 382 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 384 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 386 */ NdrFcShort( 0x20 ), /* 32 */ +/* 388 */ NdrFcShort( 0x0 ), /* 0 */ +/* 390 */ NdrFcShort( 0xe ), /* Offset= 14 (404) */ +/* 392 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 394 */ 0x0, /* 0 */ + NdrFcShort( 0xffd1 ), /* Offset= -47 (348) */ + 0x36, /* FC_POINTER */ +/* 398 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 400 */ NdrFcShort( 0xffdc ), /* Offset= -36 (364) */ +/* 402 */ 0x36, /* FC_POINTER */ + 0x5b, /* FC_END */ +/* 404 */ + 0x12, 0x0, /* FC_UP */ +/* 406 */ NdrFcShort( 0xffe2 ), /* Offset= -30 (376) */ +/* 408 */ + 0x12, 0x0, /* FC_UP */ +/* 410 */ NdrFcShort( 0xff18 ), /* Offset= -232 (178) */ +/* 412 */ + 0x12, 0x0, /* FC_UP */ +/* 414 */ NdrFcShort( 0x6c ), /* Offset= 108 (522) */ +/* 416 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x9, /* FC_ULONG */ +/* 418 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 420 */ NdrFcShort( 0xfff8 ), /* -8 */ +/* 422 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 424 */ NdrFcShort( 0x2 ), /* Offset= 2 (426) */ +/* 426 */ NdrFcShort( 0x4 ), /* 4 */ +/* 428 */ NdrFcShort( 0x3 ), /* 3 */ +/* 430 */ NdrFcLong( 0x1 ), /* 1 */ +/* 434 */ NdrFcShort( 0x10 ), /* Offset= 16 (450) */ +/* 436 */ NdrFcLong( 0x2 ), /* 2 */ +/* 440 */ NdrFcShort( 0xa ), /* Offset= 10 (450) */ +/* 442 */ NdrFcLong( 0x3 ), /* 3 */ +/* 446 */ NdrFcShort( 0x32 ), /* Offset= 50 (496) */ +/* 448 */ NdrFcShort( 0xffff ), /* Offset= -1 (447) */ +/* 450 */ + 0x12, 0x0, /* FC_UP */ +/* 452 */ NdrFcShort( 0x18 ), /* Offset= 24 (476) */ +/* 454 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 456 */ NdrFcLong( 0x0 ), /* 0 */ +/* 460 */ NdrFcLong( 0x10000 ), /* 65536 */ +/* 464 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 466 */ NdrFcShort( 0x2 ), /* 2 */ +/* 468 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 470 */ NdrFcShort( 0x8 ), /* 8 */ +/* 472 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 474 */ 0x5, /* FC_WCHAR */ + 0x5b, /* FC_END */ +/* 476 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 478 */ NdrFcShort( 0x10 ), /* 16 */ +/* 480 */ NdrFcShort( 0x0 ), /* 0 */ +/* 482 */ NdrFcShort( 0xa ), /* Offset= 10 (492) */ +/* 484 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 486 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 488 */ NdrFcShort( 0xffde ), /* Offset= -34 (454) */ +/* 490 */ 0x36, /* FC_POINTER */ + 0x5b, /* FC_END */ +/* 492 */ + 0x12, 0x0, /* FC_UP */ +/* 494 */ NdrFcShort( 0xffe2 ), /* Offset= -30 (464) */ +/* 496 */ + 0x12, 0x0, /* FC_UP */ +/* 498 */ NdrFcShort( 0x2 ), /* Offset= 2 (500) */ +/* 500 */ + 0x15, /* FC_STRUCT */ + 0x7, /* 7 */ +/* 502 */ NdrFcShort( 0x8 ), /* 8 */ +/* 504 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 506 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 508 */ NdrFcShort( 0x10 ), /* 16 */ +/* 510 */ NdrFcShort( 0x0 ), /* 0 */ +/* 512 */ NdrFcShort( 0x0 ), /* Offset= 0 (512) */ +/* 514 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 516 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 518 */ 0x0, /* 0 */ + NdrFcShort( 0xff99 ), /* Offset= -103 (416) */ + 0x5b, /* FC_END */ +/* 522 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 524 */ NdrFcShort( 0x30 ), /* 48 */ +/* 526 */ NdrFcShort( 0x0 ), /* 0 */ +/* 528 */ NdrFcShort( 0x0 ), /* Offset= 0 (528) */ +/* 530 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 532 */ NdrFcShort( 0xff6c ), /* Offset= -148 (384) */ +/* 534 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 536 */ NdrFcShort( 0xffe2 ), /* Offset= -30 (506) */ +/* 538 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 540 */ + 0x12, 0x0, /* FC_UP */ +/* 542 */ NdrFcShort( 0xffdc ), /* Offset= -36 (506) */ +/* 544 */ + 0x12, 0x0, /* FC_UP */ +/* 546 */ NdrFcShort( 0x18 ), /* Offset= 24 (570) */ +/* 548 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 550 */ NdrFcLong( 0x0 ), /* 0 */ +/* 554 */ NdrFcLong( 0x10000 ), /* 65536 */ +/* 558 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 560 */ NdrFcShort( 0x1 ), /* 1 */ +/* 562 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 564 */ NdrFcShort( 0x14 ), /* 20 */ +/* 566 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 568 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 570 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 572 */ NdrFcShort( 0x1c ), /* 28 */ +/* 574 */ NdrFcShort( 0x0 ), /* 0 */ +/* 576 */ NdrFcShort( 0xc ), /* Offset= 12 (588) */ +/* 578 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 580 */ NdrFcShort( 0xfe6e ), /* Offset= -402 (178) */ +/* 582 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 584 */ NdrFcShort( 0xffdc ), /* Offset= -36 (548) */ +/* 586 */ 0x36, /* FC_POINTER */ + 0x5b, /* FC_END */ +/* 588 */ + 0x12, 0x0, /* FC_UP */ +/* 590 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (558) */ +/* 592 */ + 0x12, 0x0, /* FC_UP */ +/* 594 */ NdrFcShort( 0x1e ), /* Offset= 30 (624) */ +/* 596 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x9, /* FC_ULONG */ +/* 598 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 600 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 602 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 604 */ NdrFcShort( 0x2 ), /* Offset= 2 (606) */ +/* 606 */ NdrFcShort( 0x4 ), /* 4 */ +/* 608 */ NdrFcShort( 0x2 ), /* 2 */ +/* 610 */ NdrFcLong( 0x5643 ), /* 22083 */ +/* 614 */ NdrFcShort( 0xfdfe ), /* Offset= -514 (100) */ +/* 616 */ NdrFcLong( 0x4054 ), /* 16468 */ +/* 620 */ NdrFcShort( 0xffb4 ), /* Offset= -76 (544) */ +/* 622 */ NdrFcShort( 0xffff ), /* Offset= -1 (621) */ +/* 624 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x7, /* 7 */ +/* 626 */ NdrFcShort( 0x10 ), /* 16 */ +/* 628 */ NdrFcShort( 0x0 ), /* 0 */ +/* 630 */ NdrFcShort( 0x0 ), /* Offset= 0 (630) */ +/* 632 */ 0xb, /* FC_HYPER */ + 0x8, /* FC_LONG */ +/* 634 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 636 */ NdrFcShort( 0xffd8 ), /* Offset= -40 (596) */ +/* 638 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 640 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 642 */ NdrFcShort( 0x8 ), /* 8 */ +/* 644 */ NdrFcShort( 0x0 ), /* 0 */ +/* 646 */ NdrFcShort( 0x0 ), /* Offset= 0 (646) */ +/* 648 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 650 */ 0x0, /* 0 */ + NdrFcShort( 0xfd7b ), /* Offset= -645 (6) */ + 0x5b, /* FC_END */ +/* 654 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */ +/* 656 */ NdrFcShort( 0x2 ), /* Offset= 2 (658) */ +/* 658 */ + 0x12, 0x0, /* FC_UP */ +/* 660 */ NdrFcShort( 0xffec ), /* Offset= -20 (640) */ +/* 662 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 664 */ NdrFcShort( 0x2 ), /* Offset= 2 (666) */ +/* 666 */ 0x30, /* FC_BIND_CONTEXT */ + 0xa0, /* Ctxt flags: via ptr, out, */ +/* 668 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 670 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 672 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 674 */ 0x30, /* FC_BIND_CONTEXT */ + 0x41, /* Ctxt flags: in, can't be null */ +/* 676 */ 0x1, /* 1 */ + 0x0, /* 0 */ +/* 678 */ + 0x11, 0x0, /* FC_RP */ +/* 680 */ NdrFcShort( 0x56 ), /* Offset= 86 (766) */ +/* 682 */ 0xb7, /* FC_RANGE */ + 0x8, /* 8 */ +/* 684 */ NdrFcLong( 0x0 ), /* 0 */ +/* 688 */ NdrFcLong( 0x32 ), /* 50 */ +/* 692 */ 0xb7, /* FC_RANGE */ + 0x6, /* 6 */ +/* 694 */ NdrFcLong( 0x0 ), /* 0 */ +/* 698 */ NdrFcLong( 0x3 ), /* 3 */ +/* 702 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 704 */ NdrFcShort( 0x4 ), /* 4 */ +/* 706 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 708 */ NdrFcShort( 0x4 ), /* 4 */ +/* 710 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 712 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 714 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 716 */ NdrFcShort( 0x4 ), /* 4 */ +/* 718 */ NdrFcShort( 0x0 ), /* 0 */ +/* 720 */ NdrFcShort( 0x1 ), /* 1 */ +/* 722 */ NdrFcShort( 0x0 ), /* 0 */ +/* 724 */ NdrFcShort( 0x0 ), /* 0 */ +/* 726 */ 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 728 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 730 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 732 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 734 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 736 */ NdrFcShort( 0x4 ), /* 4 */ +/* 738 */ 0x17, /* Corr desc: field pointer, FC_USHORT */ + 0x0, /* */ +/* 740 */ NdrFcShort( 0xc ), /* 12 */ +/* 742 */ NdrFcShort( 0x0 ), /* Corr flags: */ +/* 744 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 746 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 748 */ NdrFcShort( 0x4 ), /* 4 */ +/* 750 */ NdrFcShort( 0x0 ), /* 0 */ +/* 752 */ NdrFcShort( 0x1 ), /* 1 */ +/* 754 */ NdrFcShort( 0x0 ), /* 0 */ +/* 756 */ NdrFcShort( 0x0 ), /* 0 */ +/* 758 */ 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 760 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 762 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 764 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 766 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 768 */ NdrFcShort( 0x14 ), /* 20 */ +/* 770 */ NdrFcShort( 0x0 ), /* 0 */ +/* 772 */ NdrFcShort( 0x10 ), /* Offset= 16 (788) */ +/* 774 */ 0x36, /* FC_POINTER */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 776 */ 0x0, /* 0 */ + NdrFcShort( 0xffa1 ), /* Offset= -95 (682) */ + 0x36, /* FC_POINTER */ +/* 780 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 782 */ NdrFcShort( 0xffa6 ), /* Offset= -90 (692) */ +/* 784 */ 0x3e, /* FC_STRUCTPAD2 */ + 0x8, /* FC_LONG */ +/* 786 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 788 */ + 0x12, 0x0, /* FC_UP */ +/* 790 */ NdrFcShort( 0xffa8 ), /* Offset= -88 (702) */ +/* 792 */ + 0x12, 0x0, /* FC_UP */ +/* 794 */ NdrFcShort( 0xffc4 ), /* Offset= -60 (734) */ +/* 796 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 798 */ NdrFcShort( 0x2 ), /* Offset= 2 (800) */ +/* 800 */ 0x30, /* FC_BIND_CONTEXT */ + 0xa0, /* Ctxt flags: via ptr, out, */ +/* 802 */ 0x2, /* 2 */ + 0x1, /* 1 */ +/* 804 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 806 */ NdrFcShort( 0x2 ), /* Offset= 2 (808) */ +/* 808 */ 0x30, /* FC_BIND_CONTEXT */ + 0xe1, /* Ctxt flags: via ptr, in, out, can't be null */ +/* 810 */ 0x3, /* 3 */ + 0x0, /* 0 */ +/* 812 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 814 */ NdrFcShort( 0x2 ), /* Offset= 2 (816) */ +/* 816 */ 0x30, /* FC_BIND_CONTEXT */ + 0xe1, /* Ctxt flags: via ptr, in, out, can't be null */ +/* 818 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 820 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 822 */ NdrFcShort( 0x1 ), /* 1 */ +/* 824 */ 0x40, /* Corr desc: constant, val=32768 */ + 0x0, /* 0 */ +/* 826 */ NdrFcShort( 0x8000 ), /* -32768 */ +/* 828 */ NdrFcShort( 0x1 ), /* Corr flags: early, */ +/* 830 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ + + 0x0 + } + }; + +static const unsigned short TsProxyRpcInterface_FormatStringOffsetTable[] = + { + 0, + 28, + 82, + 136, + 196, + 256, + 284, + 326, + 368, + 408 + }; + + +static const MIDL_STUB_DESC TsProxyRpcInterface_StubDesc = + { + (void *)& TsProxyRpcInterface___RpcClientInterface, + MIDL_user_allocate, + MIDL_user_free, + { &TsProxyRpcInterface__MIDL_AutoBindHandle }, + 0, + 0, + 0, + 0, + ms2Dtsgu__MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x50002, /* Ndr library version */ + 0, + 0x700022b, /* MIDL Version 7.0.555 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 0x1, /* MIDL flag */ + 0, /* cs routines */ + 0, /* proxy/server info */ + 0 + }; + +/** + * END OF GENERATED CODE + */ + uint8 tsg_packet1[108] = { 0x43, 0x56, 0x00, 0x00, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, 0x54, 0x43, 0x56, @@ -276,7 +1513,10 @@ uint8 tsg_packet1[108] = 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? 00 00 00 00 0a 05 0c 00 00 00 00 00 01 00 00 00 - 9d 13 89 41 2e 85 76 3f 00 00 00 00 + 9d 13 89 41 + + UINT32 TunnelId: 2e 85 76 3f + HRESULT ReturnValue: 00 00 00 00 */ uint8 tsg_packet2[112] = @@ -367,6 +1607,8 @@ uint8 tsg_packet5[20] = 0x00, 0x00, 0x00, 0x00 }; +#if 0 + void Opnum0NotUsedOnWire(handle_t IDL_handle) { @@ -416,6 +1658,8 @@ DWORD TsProxySetupReceivePipe(handle_t IDL_handle, byte pRpcMessage[]) return 0; } +#endif + DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, uint32* lengths) { STREAM* s; From 3e2b1859898da80dce35665ecc656fd0bcf2fd6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 28 Apr 2012 22:27:04 -0400 Subject: [PATCH 33/47] libfreerdp-core: started implementing NdrClientCall2 --- libfreerdp-core/ndr.c | 31 +++++++++++++++++++ libfreerdp-core/ndr.h | 41 +++++++++++++++++++++++++ libfreerdp-core/tsg.c | 70 +++++++++++-------------------------------- 3 files changed, 89 insertions(+), 53 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index ed8c627f3..6a3a083e5 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -28,10 +28,41 @@ CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...) { + unsigned char oiFlags; + unsigned short procNum; + unsigned short stackSize; + unsigned char numberParams; + NDR_PROC_HEADER* procHeader; CLIENT_CALL_RETURN client_call_return; + procNum = stackSize = numberParams = 0; + procHeader = (NDR_PROC_HEADER*) &pFormat[0]; + client_call_return.Pointer = NULL; + oiFlags = procHeader->OiFlags; + procNum = procHeader->ProcNum; + stackSize = procHeader->StackSize; + pFormat += sizeof(NDR_PROC_HEADER); + + if (pStubDescriptor->Version >= 0x20000) + { + NDR_PROC_OI2_HEADER* procHeaderOi2 = (NDR_PROC_OI2_HEADER*) pFormat; + + oiFlags = procHeaderOi2->Oi2Flags; + numberParams = procHeaderOi2->NumberParams; + + if (oiFlags & OI2_FLAG_HAS_EXTENSIONS) + { + NDR_PROC_HEADER_EXTS* extensions = (NDR_PROC_HEADER_EXTS*) pFormat; + + pFormat += extensions->Size; + } + } + + printf("ProcHeader: ProcNum:%d OiFlags: 0x%02X, handleType: 0x%02X StackSize: %d NumberParams: %d\n", + procNum, oiFlags, procHeader->HandleType, stackSize, numberParams); + return client_call_return; } diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index 0989dfb2a..d514eb954 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -222,6 +222,41 @@ typedef struct _MIDL_STUB_DESC typedef const MIDL_STUB_DESC *PMIDL_STUB_DESC; +#define OI2_FLAG_SERVER_MUST_SIZE 0x01 +#define OI2_FLAG_CLIENT_MUST_SIZE 0x02 +#define OI2_FLAG_HAS_RETURN 0x04 +#define OI2_FLAG_HAS_PIPES 0x08 +#define OI2_FLAG_HAS_ASYNC_UUID 0x20 +#define OI2_FLAG_HAS_EXTENSIONS 0x40 +#define OI2_FLAG_HAS_ASYNC_HANDLE 0x80 + +typedef struct +{ + unsigned char Size; + unsigned char Flags2; + unsigned short ClientCorrHint; + unsigned short ServerCorrHint; + unsigned short NotifyIndex; +} NDR_PROC_HEADER_EXTS; + +typedef struct _NDR_PROC_HEADER +{ + unsigned char HandleType; + unsigned char OiFlags; + unsigned short RpcFlagsLow; + unsigned short RpcFlagsHi; + unsigned short ProcNum; + unsigned short StackSize; +} NDR_PROC_HEADER; + +typedef struct _NDR_PROC_OI2_HEADER +{ + unsigned short ClientBufferSize; + unsigned short ServerBufferSize; + unsigned int Oi2Flags; + unsigned char NumberParams; +} NDR_PROC_OI2_HEADER; + /* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ #define FC_BYTE 0x01 @@ -242,6 +277,12 @@ typedef const MIDL_STUB_DESC *PMIDL_STUB_DESC; #define FC_INT3264 0xB8 #define FC_UINT3264 0xB9 +#define FC_BIND_CONTEXT 0x30 +#define FC_BIND_GENERIC 0x31 +#define FC_BIND_PRIMITIVE 0x32 +#define FC_AUTO_HANDLE 0x33 +#define FC_CALLBACK_HANDLE 0x34 + #define NdrFcShort(s) (byte)(s & 0xFF), (byte)(s >> 8) #define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \ diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index d570083e4..01ffe570b 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -1607,59 +1607,6 @@ uint8 tsg_packet5[20] = 0x00, 0x00, 0x00, 0x00 }; -#if 0 - -void Opnum0NotUsedOnWire(handle_t IDL_handle) -{ - -} - -HRESULT TsProxyCreateTunnel(PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse, - PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext, unsigned long* tunnelId) -{ - return 0; -} - -HRESULT TsProxyAuthorizeTunnel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, - PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse) -{ - return 0; -} - -HRESULT TsProxyMakeTunnelCall(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, - unsigned long procId, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPacketResponse) -{ - return 0; -} - -HRESULT TsProxyCreateChannel(PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, - PTSENDPOINTINFO tsEndPointInfo, PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, unsigned long* channelId) -{ - return 0; -} - -void Opnum5NotUsedOnWire(handle_t IDL_handle) -{ - -} - -HRESULT TsProxyCloseChannel(PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* context) -{ - return 0; -} - -HRESULT TsProxyCloseTunnel(PTUNNEL_CONTEXT_HANDLE_SERIALIZE* context) -{ - return 0; -} - -DWORD TsProxySetupReceivePipe(handle_t IDL_handle, byte pRpcMessage[]) -{ - return 0; -} - -#endif - DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, uint32* lengths) { STREAM* s; @@ -1770,6 +1717,15 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_SERIALIZE tunnelContext; + unsigned long tunnelId; + + TsProxyCreateTunnel(&tsgPacket, &tsgPacketResponse, &tunnelContext, &tunnelId); + } + DEBUG_TSG("TsProxyCreateTunnel"); status = rpc_tsg_write(rpc, tsg_packet1, sizeof(tsg_packet1), 1); @@ -1810,6 +1766,14 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * */ + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + + TsProxyAuthorizeTunnel(&tunnelContext, &tsgPacket, &tsgPacketResponse); + } + DEBUG_TSG("TsProxyAuthorizeTunnel"); status = rpc_tsg_write(rpc, tsg_packet2, sizeof(tsg_packet2), 2); From e9e8e513325cebcce6588023bf1ad9d40116b9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 28 Apr 2012 23:37:07 -0400 Subject: [PATCH 34/47] libfreerdp-core: expand NDR API --- libfreerdp-core/ndr.c | 98 ++++++++++++++++++++++++++++++++++++++++++- libfreerdp-core/ndr.h | 51 +++++++++++++++++----- 2 files changed, 137 insertions(+), 12 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index 6a3a083e5..0b40dba38 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -26,13 +26,92 @@ * http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/ */ -CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...) +void ndr_print_param_attributes(unsigned short attributes) { + if (attributes & PARAM_ATTRIBUTE_SERVER_ALLOC_SIZE) + printf("ServerAllocSize, "); + if (attributes & PARAM_ATTRIBUTE_SAVE_FOR_ASYNC_FINISH) + printf("SaveForAsyncFinish, "); + if (attributes & PARAM_ATTRIBUTE_IS_DONT_CALL_FREE_INST) + printf("IsDontCallFreeInst, "); + if (attributes & PARAM_ATTRIBUTE_IS_SIMPLE_REF) + printf("IsSimpleRef, "); + if (attributes & PARAM_ATTRIBUTE_IS_BY_VALUE) + printf("IsByValue, "); + if (attributes & PARAM_ATTRIBUTE_IS_BASE_TYPE) + printf("IsBaseType, "); + if (attributes & PARAM_ATTRIBUTE_IS_RETURN) + printf("IsReturn, "); + if (attributes & PARAM_ATTRIBUTE_IS_OUT) + printf("IsOut, "); + if (attributes & PARAM_ATTRIBUTE_IS_IN) + printf("IsIn, "); + if (attributes & PARAM_ATTRIBUTE_IS_PIPE) + printf("IsPipe, "); + if (attributes & PARAM_ATTRIBUTE_MUST_FREE) + printf("MustFree, "); + if (attributes & PARAM_ATTRIBUTE_MUST_SIZE) + printf("MustSize, "); +} + +void ndr_process_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void** fpuArgs, unsigned short numberParams) +{ + unsigned int i; + NDR_PARAM* params; + PFORMAT_STRING fmt; + unsigned char* arg; + + params = (NDR_PARAM*) pFormat; + + printf("Params = \n{\n"); + + for (i = 0; i < numberParams; i++) + { + arg = pStubMsg->StackTop + params[i].StackOffset; + fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset]; + + printf("\t#%d\t", i); + + ndr_print_param_attributes(params[i].Attributes); + + if (params[i].Attributes & PARAM_ATTRIBUTE_IS_IN) + { + + } + + printf("\n"); + } + + printf("}\n"); +} + +void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum) +{ + pRpcMessage->Handle = NULL; + pRpcMessage->RpcFlags = 0; + pRpcMessage->ProcNum = ProcNum; + pRpcMessage->DataRepresentation = 0; + pRpcMessage->ReservedForRuntime = NULL; + pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation; + + pStubMsg->RpcMsg = pRpcMessage; + pStubMsg->BufferStart = NULL; + pStubMsg->BufferEnd = NULL; + pStubMsg->BufferLength = 0; + pStubMsg->StackTop = NULL; + pStubMsg->StubDesc = pStubDesc; +} + +CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack) +{ + RPC_MESSAGE rpcMsg; unsigned char oiFlags; unsigned short procNum; unsigned short stackSize; unsigned char numberParams; NDR_PROC_HEADER* procHeader; + MIDL_STUB_MESSAGE stubMsg; CLIENT_CALL_RETURN client_call_return; procNum = stackSize = numberParams = 0; @@ -60,9 +139,26 @@ CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRIN } } + NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDescriptor, procNum); + stubMsg.StackTop = (unsigned char*) stackTop; + printf("ProcHeader: ProcNum:%d OiFlags: 0x%02X, handleType: 0x%02X StackSize: %d NumberParams: %d\n", procNum, oiFlags, procHeader->HandleType, stackSize, numberParams); + ndr_process_args(&stubMsg, pFormat, fpuStack, numberParams); + + return client_call_return; +} + +CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...) +{ + va_list args; + CLIENT_CALL_RETURN client_call_return; + + va_start(args, pFormat); + client_call_return = ndr_client_call(pStubDescriptor, pFormat, va_arg(args, void**), NULL); + va_end(args); + return client_call_return; } diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index d514eb954..4769b7e72 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -132,6 +132,9 @@ typedef void (*NDR_NOTIFY_ROUTINE)(void); typedef const unsigned char* PFORMAT_STRING; +typedef struct _MIDL_STUB_DESC MIDL_STUB_DESC; +typedef MIDL_STUB_DESC* PMIDL_STUB_DESC; + typedef struct _MIDL_STUB_MESSAGE { PRPC_MESSAGE RpcMsg; @@ -142,7 +145,9 @@ typedef struct _MIDL_STUB_MESSAGE unsigned long BufferLength; unsigned long MemorySize; unsigned char* Memory; -} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; + unsigned char* StackTop; + PMIDL_STUB_DESC StubDesc; +} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; typedef struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; @@ -186,7 +191,7 @@ typedef struct _COMM_FAULT_OFFSETS typedef void* NDR_CS_ROUTINES; typedef void* NDR_EXPR_DESC; -typedef struct _MIDL_STUB_DESC +struct _MIDL_STUB_DESC { void* RpcInterfaceInformation; void* (*pfnAllocate)(size_t); @@ -218,17 +223,41 @@ typedef struct _MIDL_STUB_DESC const NDR_CS_ROUTINES* CsRoutineTables; void* ProxyServerInfo; const NDR_EXPR_DESC* pExprInfo; -} MIDL_STUB_DESC; +}; -typedef const MIDL_STUB_DESC *PMIDL_STUB_DESC; +#define OI2_FLAG_SERVER_MUST_SIZE 0x01 +#define OI2_FLAG_CLIENT_MUST_SIZE 0x02 +#define OI2_FLAG_HAS_RETURN 0x04 +#define OI2_FLAG_HAS_PIPES 0x08 +#define OI2_FLAG_HAS_ASYNC_UUID 0x20 +#define OI2_FLAG_HAS_EXTENSIONS 0x40 +#define OI2_FLAG_HAS_ASYNC_HANDLE 0x80 -#define OI2_FLAG_SERVER_MUST_SIZE 0x01 -#define OI2_FLAG_CLIENT_MUST_SIZE 0x02 -#define OI2_FLAG_HAS_RETURN 0x04 -#define OI2_FLAG_HAS_PIPES 0x08 -#define OI2_FLAG_HAS_ASYNC_UUID 0x20 -#define OI2_FLAG_HAS_EXTENSIONS 0x40 -#define OI2_FLAG_HAS_ASYNC_HANDLE 0x80 +#define PARAM_ATTRIBUTE_SERVER_ALLOC_SIZE 0xE000 +#define PARAM_ATTRIBUTE_SAVE_FOR_ASYNC_FINISH 0x0400 +#define PARAM_ATTRIBUTE_IS_DONT_CALL_FREE_INST 0x0200 +#define PARAM_ATTRIBUTE_IS_SIMPLE_REF 0x0100 +#define PARAM_ATTRIBUTE_IS_BY_VALUE 0x0080 +#define PARAM_ATTRIBUTE_IS_BASE_TYPE 0x0040 +#define PARAM_ATTRIBUTE_IS_RETURN 0x0020 +#define PARAM_ATTRIBUTE_IS_OUT 0x0010 +#define PARAM_ATTRIBUTE_IS_IN 0x0008 +#define PARAM_ATTRIBUTE_IS_PIPE 0x0004 +#define PARAM_ATTRIBUTE_MUST_FREE 0x0002 +#define PARAM_ATTRIBUTE_MUST_SIZE 0x0001 + +typedef struct +{ + unsigned short Attributes; + unsigned short StackOffset; + + union + { + unsigned char FormatChar; + unsigned short Offset; + } Type; + +} NDR_PARAM; typedef struct { From a8fb709b35c66baa1542f88ad289045caf9024b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 30 Apr 2012 21:12:34 -0400 Subject: [PATCH 35/47] libfreerdp-core: improve generated NDR header parsing --- libfreerdp-core/ndr.c | 284 +++++++++++++++++++++++++++++++++++++----- libfreerdp-core/ndr.h | 174 ++++++++++++++++++++++---- libfreerdp-core/tsg.c | 17 +++ 3 files changed, 419 insertions(+), 56 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index 0b40dba38..d46e55114 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -26,40 +26,187 @@ * http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/ */ -void ndr_print_param_attributes(unsigned short attributes) +const char* FC_TYPE_STRINGS[] = { - if (attributes & PARAM_ATTRIBUTE_SERVER_ALLOC_SIZE) + "FC_ZERO", + "FC_BYTE", + "FC_CHAR", + "FC_SMALL", + "FC_USMALL", + "FC_WCHAR", + "FC_SHORT", + "FC_USHORT", + "FC_LONG", + "FC_ULONG", + "FC_FLOAT", + "FC_HYPER", + "FC_DOUBLE", + "FC_ENUM16", + "FC_ENUM32", + "FC_IGNORE", + "FC_ERROR_STATUS_T", + "FC_RP", + "FC_UP", + "FC_OP", + "FC_FP", + "FC_STRUCT", + "FC_PSTRUCT", + "FC_CSTRUCT", + "FC_CPSTRUCT", + "FC_CVSTRUCT", + "FC_BOGUS_STRUCT", + "FC_CARRAY", + "FC_CVARRAY", + "FC_SMFARRAY", + "FC_LGFARRAY", + "FC_SMVARRAY", + "FC_LGVARRAY", + "FC_BOGUS_ARRAY", + "FC_C_CSTRING", + "FC_C_BSTRING", + "FC_C_SSTRING", + "FC_C_WSTRING", + "FC_CSTRING", + "FC_BSTRING", + "FC_SSTRING", + "FC_WSTRING", + "FC_ENCAPSULATED_UNION", + "FC_NON_ENCAPSULATED_UNION", + "FC_BYTE_COUNT_POINTER", + "FC_TRANSMIT_AS", + "FC_REPRESENT_AS", + "FC_IP", + "FC_BIND_CONTEXT", + "FC_BIND_GENERIC", + "FC_BIND_PRIMITIVE", + "FC_AUTO_HANDLE", + "FC_CALLBACK_HANDLE", + "FC_UNUSED1", + "FC_POINTER", + "FC_ALIGNM2", + "FC_ALIGNM4", + "FC_ALIGNM8", + "FC_UNUSED2", + "FC_UNUSED3", + "FC_UNUSED4", + "FC_STRUCTPAD1", + "FC_STRUCTPAD2", + "FC_STRUCTPAD3", + "FC_STRUCTPAD4", + "FC_STRUCTPAD5", + "FC_STRUCTPAD6", + "FC_STRUCTPAD7", + "FC_STRING_SIZED", + "FC_UNUSED5", + "FC_NO_REPEAT", + "FC_FIXED_REPEAT", + "FC_VARIABLE_REPEAT", + "FC_FIXED_OFFSET", + "FC_VARIABLE_OFFSET", + "FC_PP", + "FC_EMBEDDED_COMPLEX", + "FC_IN_PARAM", + "FC_IN_PARAM_BASETYPE", + "FC_IN_PARAM_NO_FREE_INST", + "FC_IN_OUT_PARAM", + "FC_OUT_PARAM", + "FC_RETURN_PARAM", + "FC_RETURN_PARAM_BASETYPE", + "FC_DEREFERENCE", + "FC_DIV_2", + "FC_MULT_2", + "FC_ADD_1", + "FC_SUB_1", + "FC_CALLBACK", + "FC_CONSTANT_IID", + "FC_END", + "FC_PAD", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "FC_SPLIT_DEREFERENCE", + "FC_SPLIT_DIV_2", + "FC_SPLIT_MULT_2", + "FC_SPLIT_ADD_1", + "FC_SPLIT_SUB_1", + "FC_SPLIT_CALLBACK", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "FC_HARD_STRUCT", + "FC_TRANSMIT_AS_PTR", + "FC_REPRESENT_AS_PTR", + "FC_USER_MARSHAL", + "FC_PIPE", + "FC_BLKHOLE", + "FC_RANGE", + "FC_INT3264", + "FC_UINT3264", + "FC_END_OF_UNIVERSE", +}; + +void ndr_print_param_attributes(PARAM_ATTRIBUTES attributes) +{ + if (attributes.ServerAllocSize) printf("ServerAllocSize, "); - if (attributes & PARAM_ATTRIBUTE_SAVE_FOR_ASYNC_FINISH) + if (attributes.SaveForAsyncFinish) printf("SaveForAsyncFinish, "); - if (attributes & PARAM_ATTRIBUTE_IS_DONT_CALL_FREE_INST) + if (attributes.IsDontCallFreeInst) printf("IsDontCallFreeInst, "); - if (attributes & PARAM_ATTRIBUTE_IS_SIMPLE_REF) + if (attributes.IsSimpleRef) printf("IsSimpleRef, "); - if (attributes & PARAM_ATTRIBUTE_IS_BY_VALUE) + if (attributes.IsByValue) printf("IsByValue, "); - if (attributes & PARAM_ATTRIBUTE_IS_BASE_TYPE) + if (attributes.IsBasetype) printf("IsBaseType, "); - if (attributes & PARAM_ATTRIBUTE_IS_RETURN) + if (attributes.IsReturn) printf("IsReturn, "); - if (attributes & PARAM_ATTRIBUTE_IS_OUT) + if (attributes.IsOut) printf("IsOut, "); - if (attributes & PARAM_ATTRIBUTE_IS_IN) + if (attributes.IsIn) printf("IsIn, "); - if (attributes & PARAM_ATTRIBUTE_IS_PIPE) + if (attributes.IsPipe) printf("IsPipe, "); - if (attributes & PARAM_ATTRIBUTE_MUST_FREE) + if (attributes.MustFree) printf("MustFree, "); - if (attributes & PARAM_ATTRIBUTE_MUST_SIZE) + if (attributes.MustSize) printf("MustSize, "); } -void ndr_process_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void** fpuArgs, unsigned short numberParams) +void ndr_process_param(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, NDR_PARAM* param) +{ + unsigned char id; + PFORMAT_STRING pFormat; + + /* Parameter Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374362/ */ + + if (param->Attributes.IsBasetype) + { + pFormat = ¶m->Type.FormatChar; + + if (param->Attributes.IsSimpleRef) + pMemory = *(unsigned char**) pMemory; + } + else + { + pFormat = &pStubMsg->StubDesc->pFormatTypes[param->Type.Offset]; + + if (!(param->Attributes.IsByValue)) + pMemory = *(unsigned char**) pMemory; + } + + id = (pFormat[0] & 0x7F); +} + +void ndr_process_params(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void** fpuArgs, unsigned short numberParams) { unsigned int i; NDR_PARAM* params; PFORMAT_STRING fmt; unsigned char* arg; + unsigned char type; params = (NDR_PARAM*) pFormat; @@ -67,16 +214,31 @@ void ndr_process_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void* for (i = 0; i < numberParams; i++) { + float tmp; arg = pStubMsg->StackTop + params[i].StackOffset; fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset]; +#ifdef __x86_64__ + if ((params[i].Attributes.IsBasetype) && + !(params[i].Attributes.IsSimpleRef) && + ((params[i].Type.FormatChar) == FC_FLOAT) && !fpuArgs) + { + tmp = *(double*) arg; + arg = (unsigned char*) &tmp; + } +#endif + printf("\t#%d\t", i); + type = (params[i].Attributes.IsBasetype) ? params[i].Type.FormatChar : *fmt; + + printf(" type %s (0x%02X) ", FC_TYPE_STRINGS[type & 0xBA], type); + ndr_print_param_attributes(params[i].Attributes); - if (params[i].Attributes & PARAM_ATTRIBUTE_IS_IN) + if (params[i].Attributes.IsIn) { - + ndr_process_param(pStubMsg, arg, ¶ms[i]); } printf("\n"); @@ -106,12 +268,16 @@ void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMs CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack) { RPC_MESSAGE rpcMsg; - unsigned char oiFlags; unsigned short procNum; unsigned short stackSize; unsigned char numberParams; - NDR_PROC_HEADER* procHeader; + unsigned char handleType; MIDL_STUB_MESSAGE stubMsg; + INTERPRETER_FLAGS flags; + INTERPRETER_OPT_FLAGS optFlags; + INTERPRETER_OPT_FLAGS2 extFlags; + NDR_PROC_HEADER* procHeader; + NDR_OI2_PROC_HEADER* oi2ProcHeader; CLIENT_CALL_RETURN client_call_return; procNum = stackSize = numberParams = 0; @@ -119,33 +285,83 @@ CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRI client_call_return.Pointer = NULL; - oiFlags = procHeader->OiFlags; + handleType = procHeader->HandleType; + flags = procHeader->OldOiFlags; procNum = procHeader->ProcNum; stackSize = procHeader->StackSize; pFormat += sizeof(NDR_PROC_HEADER); - if (pStubDescriptor->Version >= 0x20000) + /* The Header: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378707/ */ + /* Procedure Header Descriptor: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374387/ */ + /* Handles: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373932/ */ + + printf("Oi Header: HandleType: 0x%02X OiFlags: 0x%02X ProcNum: %d StackSize: 0x%04X\n", + handleType, *((unsigned char*) &flags), + (unsigned short) procNum, (unsigned short) stackSize); + + if (handleType > 0) { - NDR_PROC_OI2_HEADER* procHeaderOi2 = (NDR_PROC_OI2_HEADER*) pFormat; - - oiFlags = procHeaderOi2->Oi2Flags; - numberParams = procHeaderOi2->NumberParams; - - if (oiFlags & OI2_FLAG_HAS_EXTENSIONS) - { - NDR_PROC_HEADER_EXTS* extensions = (NDR_PROC_HEADER_EXTS*) pFormat; - - pFormat += extensions->Size; - } + /* implicit handle */ + printf("Implicit Handle\n"); + oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[0]; + pFormat += sizeof(NDR_OI2_PROC_HEADER); + } + else + { + /* explicit handle */ + printf("Explicit Handle\n"); + oi2ProcHeader = (NDR_OI2_PROC_HEADER*) &pFormat[6]; + pFormat += sizeof(NDR_OI2_PROC_HEADER) + 6; } + optFlags = oi2ProcHeader->Oi2Flags; + numberParams = oi2ProcHeader->NumberParams; + + printf("Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d\n", + *((unsigned char*) &optFlags), + (unsigned char) numberParams); + NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDescriptor, procNum); + + if (optFlags.HasExtensions) + { + NDR_PROC_HEADER_EXTS* extensions = (NDR_PROC_HEADER_EXTS*) pFormat; + + pFormat += extensions->Size; + extFlags = extensions->Flags2; + + printf("Extensions: Size: %d, flags2: 0x%02X\n", + extensions->Size, *((unsigned char*) &extensions->Flags2)); + +#ifdef __x86_64__ + if (extensions->Size > sizeof(*extensions) && fpuStack) + { + int i; + unsigned short fpuMask = *(unsigned short*) (extensions + 1); + + for (i = 0; i < 4; i++, fpuMask >>= 2) + { + switch (fpuMask & 3) + { + case 1: *(float*) &stackTop[i] = *(float*) &fpuStack[i]; + break; + + case 2: *(double*) &stackTop[i] = *(double*) &fpuStack[i]; + break; + } + } + } +#endif + } + stubMsg.StackTop = (unsigned char*) stackTop; - printf("ProcHeader: ProcNum:%d OiFlags: 0x%02X, handleType: 0x%02X StackSize: %d NumberParams: %d\n", - procNum, oiFlags, procHeader->HandleType, stackSize, numberParams); + if (extFlags.HasNewCorrDesc) + { + printf("HasNewCorrDesc\n"); + } - ndr_process_args(&stubMsg, pFormat, fpuStack, numberParams); + ndr_process_params(&stubMsg, pFormat, fpuStack, numberParams); return client_call_return; } diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index 4769b7e72..d0748fc65 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -225,6 +225,57 @@ struct _MIDL_STUB_DESC const NDR_EXPR_DESC* pExprInfo; }; +typedef struct +{ + unsigned char FullPtrUsed : 1; + unsigned char RpcSsAllocUsed : 1; + unsigned char ObjectProc : 1; + unsigned char HasRpcFlags : 1; + unsigned char IgnoreObjectException : 1; + unsigned char HasCommOrFault : 1; + unsigned char UseNewInitRoutines : 1; + unsigned char Unused : 1; +} INTERPRETER_FLAGS, *PINTERPRETER_FLAGS; + +typedef struct +{ + unsigned short MustSize : 1; + unsigned short MustFree : 1; + unsigned short IsPipe : 1; + unsigned short IsIn : 1; + unsigned short IsOut : 1; + unsigned short IsReturn : 1; + unsigned short IsBasetype : 1; + unsigned short IsByValue : 1; + unsigned short IsSimpleRef : 1; + unsigned short IsDontCallFreeInst : 1; + unsigned short SaveForAsyncFinish : 1; + unsigned short Unused : 2; + unsigned short ServerAllocSize : 3; +} PARAM_ATTRIBUTES, *PPARAM_ATTRIBUTES; + +typedef struct +{ + unsigned char ServerMustSize : 1; + unsigned char ClientMustSize : 1; + unsigned char HasReturn : 1; + unsigned char HasPipes : 1; + unsigned char Unused : 1; + unsigned char HasAsyncUuid : 1; + unsigned char HasExtensions : 1; + unsigned char HasAsyncHandle : 1; +} INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS; + +typedef struct +{ + unsigned char HasNewCorrDesc : 1; + unsigned char ClientCorrCheck : 1; + unsigned char ServerCorrCheck : 1; + unsigned char HasNotify : 1; + unsigned char HasNotify2 : 1; + unsigned char Unused : 3; +} INTERPRETER_OPT_FLAGS2, *PINTERPRETER_OPT_FLAGS2; + #define OI2_FLAG_SERVER_MUST_SIZE 0x01 #define OI2_FLAG_CLIENT_MUST_SIZE 0x02 #define OI2_FLAG_HAS_RETURN 0x04 @@ -233,22 +284,15 @@ struct _MIDL_STUB_DESC #define OI2_FLAG_HAS_EXTENSIONS 0x40 #define OI2_FLAG_HAS_ASYNC_HANDLE 0x80 -#define PARAM_ATTRIBUTE_SERVER_ALLOC_SIZE 0xE000 -#define PARAM_ATTRIBUTE_SAVE_FOR_ASYNC_FINISH 0x0400 -#define PARAM_ATTRIBUTE_IS_DONT_CALL_FREE_INST 0x0200 -#define PARAM_ATTRIBUTE_IS_SIMPLE_REF 0x0100 -#define PARAM_ATTRIBUTE_IS_BY_VALUE 0x0080 -#define PARAM_ATTRIBUTE_IS_BASE_TYPE 0x0040 -#define PARAM_ATTRIBUTE_IS_RETURN 0x0020 -#define PARAM_ATTRIBUTE_IS_OUT 0x0010 -#define PARAM_ATTRIBUTE_IS_IN 0x0008 -#define PARAM_ATTRIBUTE_IS_PIPE 0x0004 -#define PARAM_ATTRIBUTE_MUST_FREE 0x0002 -#define PARAM_ATTRIBUTE_MUST_SIZE 0x0001 +#define OI2_EXT_FLAG_HAS_NEW_CORR_DESC 0x01 +#define OI2_EXT_FLAG_CLIENT_CORR_CHECK 0x02 +#define OI2_EXT_FLAG_SERVER_CORR_CHECK 0x04 +#define OI2_EXT_FLAG_HAS_NOTIFY 0x08 +#define OI2_EXT_FLAG_HAS_NOTIFY2 0x10 typedef struct { - unsigned short Attributes; + PARAM_ATTRIBUTES Attributes; unsigned short StackOffset; union @@ -262,7 +306,7 @@ typedef struct typedef struct { unsigned char Size; - unsigned char Flags2; + INTERPRETER_OPT_FLAGS2 Flags2; unsigned short ClientCorrHint; unsigned short ServerCorrHint; unsigned short NotifyIndex; @@ -271,23 +315,24 @@ typedef struct typedef struct _NDR_PROC_HEADER { unsigned char HandleType; - unsigned char OiFlags; + INTERPRETER_FLAGS OldOiFlags; unsigned short RpcFlagsLow; unsigned short RpcFlagsHi; unsigned short ProcNum; unsigned short StackSize; -} NDR_PROC_HEADER; +} NDR_PROC_HEADER, *PNDR_PROC_HEADER; -typedef struct _NDR_PROC_OI2_HEADER +typedef struct _NDR_OI2_PROC_HEADER { unsigned short ClientBufferSize; unsigned short ServerBufferSize; - unsigned int Oi2Flags; + INTERPRETER_OPT_FLAGS Oi2Flags; unsigned char NumberParams; -} NDR_PROC_OI2_HEADER; +} NDR_OI2_PROC_HEADER, *PNDR_OI2_PROC_HEADER; /* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ +#define FC_ZERO 0x02 #define FC_BYTE 0x01 #define FC_CHAR 0x02 #define FC_SMALL 0x03 @@ -302,15 +347,100 @@ typedef struct _NDR_PROC_OI2_HEADER #define FC_DOUBLE 0x0C #define FC_ENUM16 0x0D #define FC_ENUM32 0x0E +#define FC_IGNORE 0x0F #define FC_ERROR_STATUS_T 0x10 -#define FC_INT3264 0xB8 -#define FC_UINT3264 0xB9 - +#define FC_RP 0x11 +#define FC_UP 0x12 +#define FC_OP 0x13 +#define FC_FP 0x14 +#define FC_STRUCT 0x15 +#define FC_PSTRUCT 0x16 +#define FC_CSTRUCT 0x17 +#define FC_CPSTRUCT 0x18 +#define FC_CVSTRUCT 0x19 +#define FC_BOGUS_STRUCT 0x1A +#define FC_CARRAY 0x1B +#define FC_CVARRAY 0x1C +#define FC_SMFARRAY 0x1D +#define FC_LGFARRAY 0x1E +#define FC_SMVARRAY 0x1F +#define FC_LGVARRAY 0x20 +#define FC_BOGUS_ARRAY 0x21 +#define FC_C_CSTRING 0x22 +#define FC_C_BSTRING 0x23 +#define FC_C_SSTRING 0x24 +#define FC_C_WSTRING 0x25 +#define FC_CSTRING 0x26 +#define FC_BSTRING 0x27 +#define FC_SSTRING 0x28 +#define FC_WSTRING 0x29 +#define FC_ENCAPSULATED_UNION 0x2A +#define FC_NON_ENCAPSULATED_UNION 0x2B +#define FC_BYTE_COUNT_POINTER 0x2C +#define FC_TRANSMIT_AS 0x2D +#define FC_REPRESENT_AS 0x2E +#define FC_IP 0x2F #define FC_BIND_CONTEXT 0x30 #define FC_BIND_GENERIC 0x31 #define FC_BIND_PRIMITIVE 0x32 #define FC_AUTO_HANDLE 0x33 #define FC_CALLBACK_HANDLE 0x34 +#define FC_UNUSED1 0x35 +#define FC_POINTER 0x36 +#define FC_ALIGNM2 0x37 +#define FC_ALIGNM4 0x38 +#define FC_ALIGNM8 0x39 +#define FC_UNUSED2 0x3A +#define FC_UNUSED3 0x3B +#define FC_UNUSED4 0x3C +#define FC_STRUCTPAD1 0x3D +#define FC_STRUCTPAD2 0x3E +#define FC_STRUCTPAD3 0x3F +#define FC_STRUCTPAD4 0x40 +#define FC_STRUCTPAD5 0x41 +#define FC_STRUCTPAD6 0x42 +#define FC_STRUCTPAD7 0x43 +#define FC_STRING_SIZED 0x44 +#define FC_UNUSED5 0x45 +#define FC_NO_REPEAT 0x46 +#define FC_FIXED_REPEAT 0x47 +#define FC_VARIABLE_REPEAT 0x48 +#define FC_FIXED_OFFSET 0x49 +#define FC_VARIABLE_OFFSET 0x4A +#define FC_PP 0x4B +#define FC_EMBEDDED_COMPLEX 0x4C +#define FC_IN_PARAM 0x4D +#define FC_IN_PARAM_BASETYPE 0x4E +#define FC_IN_PARAM_NO_FREE_INST 0x4F +#define FC_IN_OUT_PARAM 0x50 +#define FC_OUT_PARAM 0x51 +#define FC_RETURN_PARAM 0x52 +#define FC_RETURN_PARAM_BASETYPE 0x53 +#define FC_DEREFERENCE 0x54 +#define FC_DIV_2 0x55 +#define FC_MULT_2 0x56 +#define FC_ADD_1 0x57 +#define FC_SUB_1 0x58 +#define FC_CALLBACK 0x59 +#define FC_CONSTANT_IID 0x5A +#define FC_END 0x5B +#define FC_PAD 0x5C +#define FC_SPLIT_DEREFERENCE 0x74 +#define FC_SPLIT_DIV_2 0x75 +#define FC_SPLIT_MULT_2 0x76 +#define FC_SPLIT_ADD_1 0x77 +#define FC_SPLIT_SUB_1 0x78 +#define FC_SPLIT_CALLBACK 0x79 +#define FC_HARD_STRUCT 0xB1 +#define FC_TRANSMIT_AS_PTR 0xB2 +#define FC_REPRESENT_AS_PTR 0xB3 +#define FC_USER_MARSHAL 0xB4 +#define FC_PIPE 0xB5 +#define FC_BLKHOLE 0xB6 +#define FC_RANGE 0xB7 +#define FC_INT3264 0xB8 +#define FC_UINT3264 0xB9 +#define FC_END_OF_UNIVERSE 0xBA #define NdrFcShort(s) (byte)(s & 0xFF), (byte)(s >> 8) diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 01ffe570b..a2d6f7183 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -1804,6 +1804,14 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + + TsProxyMakeTunnelCall(&tunnelContext, 0, &tsgPacket, &tsgPacketResponse); + } + DEBUG_TSG("TsProxyMakeTunnelCall"); status = rpc_tsg_write(rpc, tsg_packet3, sizeof(tsg_packet3), 3); @@ -1840,6 +1848,15 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ + { + unsigned long channelId; + TSENDPOINTINFO tsEndPointInfo; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + PCHANNEL_CONTEXT_HANDLE_SERIALIZE channelContext; + + TsProxyCreateChannel(&tunnelContext, &tsEndPointInfo, &channelContext, &channelId); + } + DEBUG_TSG("TsProxyCreateChannel"); status = rpc_tsg_write(rpc, s_p4->data, s_p4->size, 4); From a135206af966cef5ffcf489efba4c81a8b8bc4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 1 May 2012 23:09:18 -0400 Subject: [PATCH 36/47] libfreerdp-core: start implement NDR buffer size methods --- include/freerdp/wtypes.h | 2 + libfreerdp-core/ndr.c | 660 ++++++++++++++++++++++++++++++++++++++- libfreerdp-core/ndr.h | 10 +- 3 files changed, 654 insertions(+), 18 deletions(-) diff --git a/include/freerdp/wtypes.h b/include/freerdp/wtypes.h index 4503d224b..fc95ac144 100644 --- a/include/freerdp/wtypes.h +++ b/include/freerdp/wtypes.h @@ -106,6 +106,8 @@ typedef unsigned short WORD, *PWORD, *LPWORD; typedef void* PCONTEXT_HANDLE; typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; +typedef unsigned long error_status_t; + typedef struct _GUID { unsigned long Data1; diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index d46e55114..a308c1306 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -147,7 +147,562 @@ const char* FC_TYPE_STRINGS[] = "FC_END_OF_UNIVERSE", }; -void ndr_print_param_attributes(PARAM_ATTRIBUTES attributes) +typedef void (*NDR_TYPE_SIZE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeBufferSize, /* FC_BYTE */ + NdrSimpleTypeBufferSize, /* FC_CHAR */ + NdrSimpleTypeBufferSize, /* FC_SMALL */ + NdrSimpleTypeBufferSize, /* FC_USMALL */ + NdrSimpleTypeBufferSize, /* FC_WCHAR */ + NdrSimpleTypeBufferSize, /* FC_SHORT */ + NdrSimpleTypeBufferSize, /* FC_USHORT */ + NdrSimpleTypeBufferSize, /* FC_LONG */ + NdrSimpleTypeBufferSize, /* FC_ULONG */ + NdrSimpleTypeBufferSize, /* FC_FLOAT */ + NdrSimpleTypeBufferSize, /* FC_HYPER */ + NdrSimpleTypeBufferSize, /* FC_DOUBLE */ + NdrSimpleTypeBufferSize, /* FC_ENUM16 */ + NdrSimpleTypeBufferSize, /* FC_ENUM32 */ + NdrSimpleTypeBufferSize, /* FC_IGNORE */ + NdrSimpleTypeBufferSize, /* FC_ERROR_STATUS_T */ + NdrPointerBufferSize, /* FC_RP */ + NdrPointerBufferSize, /* FC_UP */ + NdrPointerBufferSize, /* FC_OP */ + NdrPointerBufferSize, /* FC_FP */ + NdrSimpleStructBufferSize, /* FC_STRUCT */ + NdrSimpleStructBufferSize, /* FC_PSTRUCT */ + NdrConformantStructBufferSize, /* FC_CSTRUCT */ + NdrConformantStructBufferSize, /* FC_CPSTRUCT */ + NdrConformantVaryingStructBufferSize, /* FC_CVSTRUCT */ + NdrComplexStructBufferSize, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeMarshall, /* FC_BYTE */ + NdrSimpleTypeMarshall, /* FC_CHAR */ + NdrSimpleTypeMarshall, /* FC_SMALL */ + NdrSimpleTypeMarshall, /* FC_USMALL */ + NdrSimpleTypeMarshall, /* FC_WCHAR */ + NdrSimpleTypeMarshall, /* FC_SHORT */ + NdrSimpleTypeMarshall, /* FC_USHORT */ + NdrSimpleTypeMarshall, /* FC_LONG */ + NdrSimpleTypeMarshall, /* FC_ULONG */ + NdrSimpleTypeMarshall, /* FC_FLOAT */ + NdrSimpleTypeMarshall, /* FC_HYPER */ + NdrSimpleTypeMarshall, /* FC_DOUBLE */ + NdrSimpleTypeMarshall, /* FC_ENUM16 */ + NdrSimpleTypeMarshall, /* FC_ENUM32 */ + NdrSimpleTypeMarshall, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeUnmarshall, /* FC_BYTE */ + NdrSimpleTypeUnmarshall, /* FC_CHAR */ + NdrSimpleTypeUnmarshall, /* FC_SMALL */ + NdrSimpleTypeUnmarshall, /* FC_USMALL */ + NdrSimpleTypeUnmarshall, /* FC_WCHAR */ + NdrSimpleTypeUnmarshall, /* FC_SHORT */ + NdrSimpleTypeUnmarshall, /* FC_USHORT */ + NdrSimpleTypeUnmarshall, /* FC_LONG */ + NdrSimpleTypeUnmarshall, /* FC_ULONG */ + NdrSimpleTypeUnmarshall, /* FC_FLOAT */ + NdrSimpleTypeUnmarshall, /* FC_HYPER */ + NdrSimpleTypeUnmarshall, /* FC_DOUBLE */ + NdrSimpleTypeUnmarshall, /* FC_ENUM16 */ + NdrSimpleTypeUnmarshall, /* FC_ENUM32 */ + NdrSimpleTypeUnmarshall, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeFree, /* FC_BYTE */ + NdrSimpleTypeFree, /* FC_CHAR */ + NdrSimpleTypeFree, /* FC_SMALL */ + NdrSimpleTypeFree, /* FC_USMALL */ + NdrSimpleTypeFree, /* FC_WCHAR */ + NdrSimpleTypeFree, /* FC_SHORT */ + NdrSimpleTypeFree, /* FC_USHORT */ + NdrSimpleTypeFree, /* FC_LONG */ + NdrSimpleTypeFree, /* FC_ULONG */ + NdrSimpleTypeFree, /* FC_FLOAT */ + NdrSimpleTypeFree, /* FC_HYPER */ + NdrSimpleTypeFree, /* FC_DOUBLE */ + NdrSimpleTypeFree, /* FC_ENUM16 */ + NdrSimpleTypeFree, /* FC_ENUM32 */ + NdrSimpleTypeFree, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +static void AlignLength(unsigned long* length, unsigned int alignment) +{ + *length = (*length + alignment - 1) & ~(alignment - 1); +} + +static void IncrementLength(unsigned long* length, unsigned int size) +{ + *length += size; +} + +void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + switch (*pFormat) + { + case FC_BYTE: + case FC_CHAR: + case FC_SMALL: + case FC_USMALL: + IncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE)); + break; + + case FC_WCHAR: + case FC_SHORT: + case FC_USHORT: + case FC_ENUM16: + AlignLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + break; + + case FC_LONG: + case FC_ULONG: + case FC_ENUM32: + case FC_INT3264: + case FC_UINT3264: + AlignLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + break; + + case FC_FLOAT: + AlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + break; + + case FC_DOUBLE: + AlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + break; + + case FC_HYPER: + AlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + break; + + case FC_ERROR_STATUS_T: + AlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + IncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + break; + + case FC_IGNORE: + break; + } +} + +void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + unsigned char type; + PFORMAT_STRING pNextFormat; + PARAM_ATTRIBUTES* attributes; + NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine; + + type = pFormat[0]; + attributes = (PARAM_ATTRIBUTES*) &pFormat[1]; + pFormat += 2; + + if (type != FC_RP) + { + AlignLength((&pStubMsg->BufferLength), 4); + IncrementLength((&pStubMsg->BufferLength), 4); + } + + if (attributes->IsBasetype) + pNextFormat = pFormat; + else + pNextFormat = pFormat + *(SHORT*) pFormat; + + switch (type) + { + case FC_RP: + break; + + case FC_OP: + case FC_UP: + + if (!pMemory) + return; + + break; + + case FC_FP: + printf("warning: FC_FP unimplemented\n"); + break; + } + + if (attributes->IsSimpleRef) + pMemory = *(unsigned char**) pMemory; + + pfnSizeRoutine = pfnSizeRoutines[*pNextFormat]; + + if (pfnSizeRoutine) + pfnSizeRoutine(pStubMsg, pMemory, pNextFormat); +} + +void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrSimpleStructBufferSize unimplemented\n"); +} + +void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrConformantStructBufferSize unimplemented\n"); +} + +void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n"); +} + +void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrComplexStructBufferSize unimplemented\n"); +} + +void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) +{ + +} + +void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) +{ + +} + +void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + +} + +void NdrPrintParamAttributes(PARAM_ATTRIBUTES attributes) { if (attributes.ServerAllocSize) printf("ServerAllocSize, "); @@ -175,9 +730,9 @@ void ndr_print_param_attributes(PARAM_ATTRIBUTES attributes) printf("MustSize, "); } -void ndr_process_param(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, NDR_PARAM* param) +void NdrProcessParam(PMIDL_STUB_MESSAGE pStubMsg, NDR_PHASE phase, unsigned char* pMemory, NDR_PARAM* param) { - unsigned char id; + unsigned char type; PFORMAT_STRING pFormat; /* Parameter Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374362/ */ @@ -197,10 +752,42 @@ void ndr_process_param(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, NDR_ pMemory = *(unsigned char**) pMemory; } - id = (pFormat[0] & 0x7F); + type = (pFormat[0] & 0x7F); + + if (type > FC_PAD) + return; + + if (phase == NDR_PHASE_SIZE) + { + NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine = pfnSizeRoutines[type]; + + if (pfnSizeRoutine) + pfnSizeRoutine(pStubMsg, pMemory, pFormat); + } + else if (phase == NDR_PHASE_MARSHALL) + { + NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutine = pfnMarshallRoutines[type]; + + if (pfnMarshallRoutine) + pfnMarshallRoutine(pStubMsg, pMemory, *pFormat); + } + else if (phase == NDR_PHASE_UNMARSHALL) + { + NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutine = pfnUnmarshallRoutines[type]; + + if (pfnUnmarshallRoutine) + pfnUnmarshallRoutine(pStubMsg, pMemory, *pFormat); + } + else if (phase == NDR_PHASE_FREE) + { + NDR_TYPE_FREE_ROUTINE pfnFreeRoutine = pfnFreeRoutines[type]; + + if (pfnFreeRoutine) + pfnFreeRoutine(pStubMsg, pMemory, pFormat); + } } -void ndr_process_params(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void** fpuArgs, unsigned short numberParams) +void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_PHASE phase, void** fpuArgs, unsigned short numberParams) { unsigned int i; NDR_PARAM* params; @@ -232,13 +819,13 @@ void ndr_process_params(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, voi type = (params[i].Attributes.IsBasetype) ? params[i].Type.FormatChar : *fmt; - printf(" type %s (0x%02X) ", FC_TYPE_STRINGS[type & 0xBA], type); + printf(" type %s (0x%02X) ", FC_TYPE_STRINGS[type], type); - ndr_print_param_attributes(params[i].Attributes); + NdrPrintParamAttributes(params[i].Attributes); if (params[i].Attributes.IsIn) { - ndr_process_param(pStubMsg, arg, ¶ms[i]); + NdrProcessParam(pStubMsg, phase, arg, ¶ms[i]); } printf("\n"); @@ -265,7 +852,39 @@ void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMs pStubMsg->StubDesc = pStubDesc; } -CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack) +void NdrPrintOptFlags(INTERPRETER_OPT_FLAGS optFlags) +{ + if (optFlags.ClientMustSize) + printf("ClientMustSize, "); + if (optFlags.ServerMustSize) + printf("ServerMustSize, "); + if (optFlags.HasAsyncUuid) + printf("HasAsyncUiid, "); + if (optFlags.HasAsyncHandle) + printf("HasAsyncHandle, "); + if (optFlags.HasReturn) + printf("HasReturn, "); + if (optFlags.HasPipes) + printf("HasPipes, "); + if (optFlags.HasExtensions) + printf("HasExtensions, "); +} + +void NdrPrintExtFlags(INTERPRETER_OPT_FLAGS2 extFlags) +{ + if (extFlags.HasNewCorrDesc) + printf("HasNewCorrDesc, "); + if (extFlags.ClientCorrCheck) + printf("ClientCorrCheck, "); + if (extFlags.ServerCorrCheck) + printf("ServerCorrCheck, "); + if (extFlags.HasNotify) + printf("HasNotify, "); + if (extFlags.HasNotify2) + printf("HasNotify2, "); +} + +CLIENT_CALL_RETURN NdrClientCall(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, void** stackTop, void** fpuStack) { RPC_MESSAGE rpcMsg; unsigned short procNum; @@ -317,9 +936,15 @@ CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRI optFlags = oi2ProcHeader->Oi2Flags; numberParams = oi2ProcHeader->NumberParams; - printf("Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d\n", + printf("Oi2 Header: Oi2Flags: 0x%02X, NumberParams: %d ClientBufferSize: %d ServerBufferSize: %d\n", *((unsigned char*) &optFlags), - (unsigned char) numberParams); + (unsigned char) numberParams, + oi2ProcHeader->ClientBufferSize, + oi2ProcHeader->ServerBufferSize); + + printf("Oi2Flags: "); + NdrPrintOptFlags(optFlags); + printf("\n"); NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDescriptor, procNum); @@ -356,12 +981,13 @@ CLIENT_CALL_RETURN ndr_client_call(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRI stubMsg.StackTop = (unsigned char*) stackTop; - if (extFlags.HasNewCorrDesc) - { - printf("HasNewCorrDesc\n"); - } + printf("ExtFlags: "); + NdrPrintExtFlags(extFlags); + printf("\n"); - ndr_process_params(&stubMsg, pFormat, fpuStack, numberParams); + NdrProcessParams(&stubMsg, pFormat, NDR_PHASE_SIZE, fpuStack, numberParams); + + printf("stubMsg BufferLength: %d\n", (int) stubMsg.BufferLength); return client_call_return; } @@ -372,7 +998,7 @@ CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRIN CLIENT_CALL_RETURN client_call_return; va_start(args, pFormat); - client_call_return = ndr_client_call(pStubDescriptor, pFormat, va_arg(args, void**), NULL); + client_call_return = NdrClientCall(pStubDescriptor, pFormat, va_arg(args, void**), NULL); va_end(args); return client_call_return; diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index d0748fc65..3f2fbc9ea 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -330,9 +330,17 @@ typedef struct _NDR_OI2_PROC_HEADER unsigned char NumberParams; } NDR_OI2_PROC_HEADER, *PNDR_OI2_PROC_HEADER; +typedef enum _NDR_PHASE +{ + NDR_PHASE_SIZE, + NDR_PHASE_MARSHALL, + NDR_PHASE_UNMARSHALL, + NDR_PHASE_FREE +} NDR_PHASE; + /* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ -#define FC_ZERO 0x02 +#define FC_ZERO 0x00 #define FC_BYTE 0x01 #define FC_CHAR 0x02 #define FC_SMALL 0x03 From 599fcb87feb499a1af34f0ee387f7f46d8d0fdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 2 May 2012 00:17:44 -0400 Subject: [PATCH 37/47] libfreerdp-core: stub more NDR data types --- libfreerdp-core/ndr.c | 314 +++++++++++++++++++++++++++++++++++++++--- libfreerdp-core/ndr.h | 27 ++-- 2 files changed, 307 insertions(+), 34 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index a308c1306..70740b7bb 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -167,6 +167,28 @@ void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] = { NULL, /* FC_ZERO */ @@ -196,28 +218,28 @@ const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] = NdrConformantStructBufferSize, /* FC_CPSTRUCT */ NdrConformantVaryingStructBufferSize, /* FC_CVSTRUCT */ NdrComplexStructBufferSize, /* FC_BOGUS_STRUCT */ - NULL, /* FC_CARRAY */ - NULL, /* FC_CVARRAY */ - NULL, /* FC_SMFARRAY */ - NULL, /* FC_LGFARRAY */ - NULL, /* FC_SMVARRAY */ - NULL, /* FC_LGVARRAY */ - NULL, /* FC_BOGUS_ARRAY */ - NULL, /* FC_C_CSTRING */ + NdrConformantArrayBufferSize, /* FC_CARRAY */ + NdrConformantVaryingArrayBufferSize, /* FC_CVARRAY */ + NdrFixedArrayBufferSize, /* FC_SMFARRAY */ + NdrFixedArrayBufferSize, /* FC_LGFARRAY */ + NdrVaryingArrayBufferSize, /* FC_SMVARRAY */ + NdrVaryingArrayBufferSize, /* FC_LGVARRAY */ + NdrComplexArrayBufferSize, /* FC_BOGUS_ARRAY */ + NdrConformantStringBufferSize, /* FC_C_CSTRING */ NULL, /* FC_C_BSTRING */ NULL, /* FC_C_SSTRING */ - NULL, /* FC_C_WSTRING */ - NULL, /* FC_CSTRING */ + NdrConformantStringBufferSize, /* FC_C_WSTRING */ + NdrNonConformantStringBufferSize, /* FC_CSTRING */ NULL, /* FC_BSTRING */ NULL, /* FC_SSTRING */ NULL, /* FC_WSTRING */ - NULL, /* FC_ENCAPSULATED_UNION */ - NULL, /* FC_NON_ENCAPSULATED_UNION */ - NULL, /* FC_BYTE_COUNT_POINTER */ + NdrEncapsulatedUnionBufferSize, /* FC_ENCAPSULATED_UNION */ + NdrNonEncapsulatedUnionBufferSize, /* FC_NON_ENCAPSULATED_UNION */ + NdrByteCountPointerBufferSize, /* FC_BYTE_COUNT_POINTER */ NULL, /* FC_TRANSMIT_AS */ NULL, /* FC_REPRESENT_AS */ NULL, /* FC_IP */ - NULL, /* FC_BIND_CONTEXT */ + NdrContextHandleBufferSize, /* FC_BIND_CONTEXT */ NULL, /* FC_BIND_GENERIC */ NULL, /* FC_BIND_PRIMITIVE */ NULL, /* FC_AUTO_HANDLE */ @@ -618,15 +640,30 @@ void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory } } +/* Pointers: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802750/ */ + void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + /** + * pointer_type<1> + * pointer_attributes<1> + * simple_type<1> + * FC_PAD + */ + + /** + * pointer_type<1> + * pointer_attributes<1> + * offset_to_complex_description<2> + */ + unsigned char type; + unsigned char attributes; PFORMAT_STRING pNextFormat; - PARAM_ATTRIBUTES* attributes; NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine; type = pFormat[0]; - attributes = (PARAM_ATTRIBUTES*) &pFormat[1]; + attributes = pFormat[1]; pFormat += 2; if (type != FC_RP) @@ -635,30 +672,30 @@ void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, P IncrementLength((&pStubMsg->BufferLength), 4); } - if (attributes->IsBasetype) + if (attributes & FC_SIMPLE_POINTER) pNextFormat = pFormat; else pNextFormat = pFormat + *(SHORT*) pFormat; switch (type) { - case FC_RP: + case FC_RP: /* Reference Pointer */ break; - case FC_OP: - case FC_UP: + case FC_UP: /* Unique Pointer */ + case FC_OP: /* Unique Pointer in an object interface */ if (!pMemory) return; break; - case FC_FP: + case FC_FP: /* Full Pointer */ printf("warning: FC_FP unimplemented\n"); break; } - if (attributes->IsSimpleRef) + if (attributes & FC_POINTER_DEREF) pMemory = *(unsigned char**) pMemory; pfnSizeRoutine = pfnSizeRoutines[*pNextFormat]; @@ -667,26 +704,257 @@ void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, P pfnSizeRoutine(pStubMsg, pMemory, pNextFormat); } +/* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */ + void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + /** + * FC_STRUCT alignment<1> + * memory_size<2> + * member_layout<> + * FC_END + */ + + /** + * FC_PSTRUCT alignment<1> + * memory_size<2> + * pointer_layout<> + * member_layout<> + * FC_END + */ + printf("warning: NdrSimpleStructBufferSize unimplemented\n"); } void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + /** + * FC_CSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * member_layout<> + * FC_END + */ + + /** + * FC_CPSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * pointer_layout<> + * member_layout<> FC_END + */ + printf("warning: NdrConformantStructBufferSize unimplemented\n"); } void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + /** + * FC_CVSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * [pointer_layout<>] + * layout<> + * FC_END + */ + printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n"); } void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + /** + * FC_BOGUS_STRUCT + * alignment<1> + * memory_size<2> + * offset_to_conformant_array_description<2> + * offset_to_pointer_layout<2> + * member_layout<> + * FC_END + * [pointer_layout<>] + */ + + unsigned char type; + unsigned char alignment; + unsigned short memory_size; + + type = pFormat[0]; + + if (type != FC_BOGUS_STRUCT) + { + printf("error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type); + } + + alignment = pFormat[1] + 1; + memory_size = *(unsigned short*) &pFormat[2]; + + AlignLength(&(pStubMsg->BufferLength), alignment); + + if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) + { + + } + printf("warning: NdrComplexStructBufferSize unimplemented\n"); } +void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CARRAY alignment<1> + * element_size<2> + * conformance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrConformantArrayBufferSize unimplemented\n"); +} + +void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CVARRAY alignment<1> + * element_size<2> + * conformance_description<> + * variance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrConformantVaryingArrayBufferSize unimplemented\n"); +} + +void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_SMFARRAY alignment<1> + * total_size<2> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + /** + * FC_LGFARRAY alignment<1> + * total_size<4> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrFixedArrayBufferSize unimplemented\n"); +} + +void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_SMVARRAY alignment<1> + * total_size<2> + * number_elements<2> + * element_size<2> + * variance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + /** + * FC_LGVARRAY alignment<1> + * total_size<4> + * number_elements<4> + * element_size<2> + * variance_description<4> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrVaryingArrayBufferSize unimplemented\n"); +} + +void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_BOGUS_ARRAY alignment<1> + * number_of_elements<2> + * conformance_description<> + * variance_description<> + * element_description<> + * FC_END + */ + + printf("warning: NdrComplexArrayBufferSize unimplemented\n"); +} + +void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrConformantStringBufferSize unimplemented\n"); +} + +void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrNonConformantStringBufferSize unimplemented\n"); +} + +void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrEncapsulatedUnionBufferSize unimplemented\n"); +} + +void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n"); +} + +void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrByteCountPointerBufferSize unimplemented\n"); +} + +void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + unsigned char type = *pFormat; + + if (type == FC_BIND_PRIMITIVE) + { + /** + * FC_BIND_PRIMITIVE + * flag<1> + * offset<2> + */ + + printf("warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented\n"); + } + else if (type == FC_BIND_GENERIC) + { + /** + * FC_BIND_GENERIC + * flag_and_size<1> + * offset<2> + * binding_routine_pair_index<1> + * FC_PAD + */ + + printf("warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented\n"); + } + else if (type == FC_BIND_CONTEXT) + { + /** + * FC_BIND_CONTEXT + * flags<1> + * offset<2> + * context_rundown_routine_index<1> + * param_num<1> + */ + + AlignLength(&(pStubMsg->BufferLength), 4); + IncrementLength(&(pStubMsg->BufferLength), 20); + } +} + void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) { @@ -850,6 +1118,8 @@ void NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMs pStubMsg->BufferLength = 0; pStubMsg->StackTop = NULL; pStubMsg->StubDesc = pStubDesc; + pStubMsg->IgnoreEmbeddedPointers = 0; + pStubMsg->PointerLength = 0; } void NdrPrintOptFlags(INTERPRETER_OPT_FLAGS optFlags) diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index 3f2fbc9ea..a01b9e419 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -147,6 +147,8 @@ typedef struct _MIDL_STUB_MESSAGE unsigned char* Memory; unsigned char* StackTop; PMIDL_STUB_DESC StubDesc; + int IgnoreEmbeddedPointers; + unsigned long PointerLength; } MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; typedef struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; @@ -276,19 +278,20 @@ typedef struct unsigned char Unused : 3; } INTERPRETER_OPT_FLAGS2, *PINTERPRETER_OPT_FLAGS2; -#define OI2_FLAG_SERVER_MUST_SIZE 0x01 -#define OI2_FLAG_CLIENT_MUST_SIZE 0x02 -#define OI2_FLAG_HAS_RETURN 0x04 -#define OI2_FLAG_HAS_PIPES 0x08 -#define OI2_FLAG_HAS_ASYNC_UUID 0x20 -#define OI2_FLAG_HAS_EXTENSIONS 0x40 -#define OI2_FLAG_HAS_ASYNC_HANDLE 0x80 +#define FC_ALLOCATE_ALL_NODES 0x01 +#define FC_DONT_FREE 0x02 +#define FC_ALLOCED_ON_STACK 0x03 +#define FC_SIMPLE_POINTER 0x04 +#define FC_POINTER_DEREF 0x05 -#define OI2_EXT_FLAG_HAS_NEW_CORR_DESC 0x01 -#define OI2_EXT_FLAG_CLIENT_CORR_CHECK 0x02 -#define OI2_EXT_FLAG_SERVER_CORR_CHECK 0x04 -#define OI2_EXT_FLAG_HAS_NOTIFY 0x08 -#define OI2_EXT_FLAG_HAS_NOTIFY2 0x10 +#define HANDLE_PARAM_IS_VIA_PTR 0x80 +#define HANDLE_PARAM_IS_IN 0x40 +#define HANDLE_PARAM_IS_OUT 0x20 +#define HANDLE_PARAM_IS_RETURN 0x21 +#define NDR_STRICT_CONTEXT_HANDLE 0x08 +#define NDR_CONTEXT_HANDLE_NO_SERIALIZE 0x04 +#define NDR_CONTEXT_HANDLE_SERIALIZE 0x02 +#define NDR_CONTEXT_HANDLE_CANNOT_BE_NULL 0x01 typedef struct { From 8a877a83627f9a60d118b8525baf0505f5416430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 2 May 2012 04:28:44 -0400 Subject: [PATCH 38/47] libfreerdp-core: start implementation of NdrComplexStruct* --- include/freerdp/wtypes.h | 8 ++ libfreerdp-core/ndr.c | 290 ++++++++++++++++++++++++++++++++++++++- libfreerdp-core/ndr.h | 290 ++++++++++++++++++++++++--------------- 3 files changed, 470 insertions(+), 118 deletions(-) diff --git a/include/freerdp/wtypes.h b/include/freerdp/wtypes.h index fc95ac144..0f6655934 100644 --- a/include/freerdp/wtypes.h +++ b/include/freerdp/wtypes.h @@ -103,6 +103,14 @@ typedef void VOID, *PVOID, *LPVOID; typedef const void *LPCVOID; typedef unsigned short WORD, *PWORD, *LPWORD; +#if __x86_64__ +typedef __int64 INT_PTR; +typedef unsigned __int64 UINT_PTR; +#else +typedef int INT_PTR; +typedef unsigned int UINT_PTR; +#endif + typedef void* PCONTEXT_HANDLE; typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index 70740b7bb..0c8d0b472 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -761,6 +761,108 @@ void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n"); } +ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) +{ + ULONG size = 0; + + while (*pFormat != FC_END) + { + switch (*pFormat) + { + case FC_BYTE: + case FC_CHAR: + case FC_SMALL: + case FC_USMALL: + size += sizeof(BYTE); + break; + + case FC_WCHAR: + case FC_SHORT: + case FC_USHORT: + case FC_ENUM16: + size += sizeof(USHORT); + break; + + case FC_LONG: + case FC_ULONG: + case FC_ENUM32: + size += sizeof(ULONG); + break; + + case FC_INT3264: + case FC_UINT3264: + size += sizeof(INT_PTR); + break; + + case FC_FLOAT: + size += sizeof(FLOAT); + break; + + case FC_DOUBLE: + size += sizeof(DOUBLE); + break; + + case FC_HYPER: + size += sizeof(ULONGLONG); + break; + + case FC_ERROR_STATUS_T: + size += sizeof(error_status_t); + break; + + case FC_IGNORE: + break; + + case FC_RP: + case FC_UP: + case FC_OP: + case FC_FP: + case FC_POINTER: + size += sizeof(void*); + if (*pFormat != FC_POINTER) + pFormat += 4; + break; + + case FC_ALIGNM2: + AlignLength(&size, 2); + break; + + case FC_ALIGNM4: + AlignLength(&size, 4); + break; + + case FC_ALIGNM8: + AlignLength(&size, 8); + break; + + case FC_STRUCTPAD1: + case FC_STRUCTPAD2: + case FC_STRUCTPAD3: + case FC_STRUCTPAD4: + case FC_STRUCTPAD5: + case FC_STRUCTPAD6: + case FC_STRUCTPAD7: + size += *pFormat - FC_STRUCTPAD1 + 1; + break; + + case FC_PAD: + break; + + case FC_EMBEDDED_COMPLEX: + printf("warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented\n"); + break; + + default: + printf("warning: NdrComplexStructMemberSize 0x%02X unimplemented\n", *pFormat); + break; + } + + pFormat++; + } + + return size; +} + void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** @@ -777,12 +879,18 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem unsigned char type; unsigned char alignment; unsigned short memory_size; + unsigned char* pointer_layout; + unsigned char* conformant_array_description; + unsigned short offset_to_pointer_layout; + unsigned short offset_to_conformant_array_description; type = pFormat[0]; + pointer_layout = conformant_array_description = NULL; if (type != FC_BOGUS_STRUCT) { printf("error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type); + return; } alignment = pFormat[1] + 1; @@ -792,16 +900,164 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) { + unsigned long BufferLengthCopy = pStubMsg->BufferLength; + int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers; + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy; + + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = BufferLengthCopy; + } + + pFormat += 4; + + offset_to_conformant_array_description = *(unsigned short*) &pFormat[0]; + + if (offset_to_conformant_array_description) + conformant_array_description = (unsigned char*) pFormat + offset_to_conformant_array_description; + pFormat += 2; + + offset_to_pointer_layout = *(unsigned short*) &pFormat[0]; + + if (offset_to_pointer_layout) + pointer_layout = (unsigned char*) pFormat + offset_to_pointer_layout; + pFormat += 2; + + pStubMsg->Memory = pMemory; + + if (conformant_array_description) + { + ULONG size = NdrComplexStructMemberSize(pStubMsg, pFormat); } printf("warning: NdrComplexStructBufferSize unimplemented\n"); } +/* + * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/ + * + * correlation_type<1> + * correlation_operator<1> + * offset<2> + * [robust_flags<2>] + * + */ + +void NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + LPVOID ptr = NULL; + ULONG_PTR data = 0; + unsigned char type; + unsigned short offset; + unsigned char conformance; + unsigned char correlation_type; + unsigned char correlation_operator; + + correlation_type = pFormat[0]; + type = correlation_type & 0x0F; + conformance = correlation_type & 0xF0; + + correlation_operator = pFormat[1]; + offset = *(unsigned short*) & pFormat[2]; + + if (conformance == FC_NORMAL_CONFORMANCE) + { + ptr = pMemory; + } + else if (conformance == FC_POINTER_CONFORMANCE) + { + ptr = pStubMsg->Memory; + } + else if (conformance == FC_TOP_LEVEL_CONFORMANCE) + { + ptr = pStubMsg->StackTop; + } + else if (conformance == FC_CONSTANT_CONFORMANCE ) + { + data = offset | ((DWORD) pFormat[1] << 16); + pStubMsg->MaxCount = data; + } + else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE) + { + if (pStubMsg->StackTop) + ptr = pStubMsg->StackTop; + } + + switch (correlation_operator) + { + case FC_DEREFERENCE: + ptr = *(LPVOID*)((char*) ptr + offset); + break; + + case FC_DIV_2: + ptr = (char*) ptr + offset; + break; + + case FC_MULT_2: + ptr = (char*) ptr + offset; + break; + + case FC_SUB_1: + ptr = (char*) ptr + offset; + break; + + case FC_ADD_1: + ptr = (char*) ptr + offset; + break; + + case FC_CALLBACK: + { + printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n"); + } + break; + } + + switch (type) + { + case FC_LONG: + data = *(LONG*) ptr; + break; + + case FC_ULONG: + data = *(ULONG*) ptr; + break; + + case FC_SHORT: + data = *(SHORT*) ptr; + break; + + case FC_USHORT: + data = *(USHORT*) ptr; + break; + + case FC_CHAR: + case FC_SMALL: + data = *(CHAR*) ptr; + break; + + case FC_BYTE: + case FC_USMALL: + data = *(BYTE*) ptr; + break; + + case FC_HYPER: + data = *(ULONGLONG*) ptr; + break; + } +} + +void NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + +} + void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_CARRAY alignment<1> + * FC_CARRAY + * alignment<1> * element_size<2> * conformance_description<> * [pointer_layout<>] @@ -809,13 +1065,28 @@ void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pM * FC_END */ + unsigned char type; + unsigned char alignment; + unsigned short element_size; + + type = pFormat[0]; + alignment = pFormat[1] + 1; + element_size = *(unsigned short*) &pFormat[2]; + + if (type != FC_CARRAY) + { + printf("error: expected FC_CARRAY, got 0x%02X\n", type); + return; + } + printf("warning: NdrConformantArrayBufferSize unimplemented\n"); } void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_CVARRAY alignment<1> + * FC_CVARRAY + * alignment<1> * element_size<2> * conformance_description<> * variance_description<> @@ -830,7 +1101,8 @@ void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned c void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_SMFARRAY alignment<1> + * FC_SMFARRAY + * alignment<1> * total_size<2> * [pointer_layout<>] * element_description<> @@ -838,7 +1110,8 @@ void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory */ /** - * FC_LGFARRAY alignment<1> + * FC_LGFARRAY + * alignment<1> * total_size<4> * [pointer_layout<>] * element_description<> @@ -851,7 +1124,8 @@ void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_SMVARRAY alignment<1> + * FC_SMVARRAY + * alignment<1> * total_size<2> * number_elements<2> * element_size<2> @@ -862,7 +1136,8 @@ void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemo */ /** - * FC_LGVARRAY alignment<1> + * FC_LGVARRAY + * alignment<1> * total_size<4> * number_elements<4> * element_size<2> @@ -878,7 +1153,8 @@ void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemo void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_BOGUS_ARRAY alignment<1> + * FC_BOGUS_ARRAY + * alignment<1> * number_of_elements<2> * conformance_description<> * variance_description<> diff --git a/libfreerdp-core/ndr.h b/libfreerdp-core/ndr.h index a01b9e419..f5fe77264 100644 --- a/libfreerdp-core/ndr.h +++ b/libfreerdp-core/ndr.h @@ -145,10 +145,63 @@ typedef struct _MIDL_STUB_MESSAGE unsigned long BufferLength; unsigned long MemorySize; unsigned char* Memory; - unsigned char* StackTop; - PMIDL_STUB_DESC StubDesc; + int IsClient; + int ReuseBuffer; + struct NDR_ALLOC_ALL_NODES_CONTEXT* pAllocAllNodesContext; + struct NDR_POINTER_QUEUE_STATE* pPointerQueueState; int IgnoreEmbeddedPointers; + unsigned char* PointerBufferMark; + unsigned char fBufferValid; + unsigned char uFlags; + unsigned short Unused2; + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned long ActualCount; + void *(*pfnAllocate)(size_t); + void (*pfnFree)(void*); + unsigned char* StackTop; + unsigned char* pPresentedType; + unsigned char* pTransmitType; + handle_t SavedHandle; + const struct _MIDL_STUB_DESC* StubDesc; + struct _FULL_PTR_XLAT_TABLES* FullPtrXlatTables; + unsigned long FullPtrRefId; unsigned long PointerLength; + int fInDontFree : 1; + int fDontCallFreeInst : 1; + int fInOnlyParam : 1; + int fHasReturn : 1; + int fHasExtensions : 1; + int fHasNewCorrDesc : 1; + int fUnused : 10; + int fUnused2 : 16; + unsigned long dwDestContext; + void* pvDestContext; + //NDR_SCONTEXT* SavedContextHandles; + long ParamNumber; + struct IRpcChannelBuffer* pRpcChannelBuffer; + //PARRAY_INFO pArrayInfo; + unsigned long* SizePtrCountArray; + unsigned long* SizePtrOffsetArray; + unsigned long* SizePtrLengthArray; + void* pArgQueue; + unsigned long dwStubPhase; + void* LowStackMark; + //PNDR_ASYNC_MESSAGE pAsyncMsg; + //PNDR_CORRELATION_INFO pCorrInfo; + unsigned char* pCorrMemory; + void* pMemoryList; + //CS_STUB_INFO* pCSInfo; + unsigned char* ConformanceMark; + unsigned char* VarianceMark; + void* BackingStoreLowMark; + INT_PTR Unused; + struct _NDR_PROC_CONTEXT* pContext; + INT_PTR Reserved51_1; + INT_PTR Reserved51_2; + INT_PTR Reserved51_3; + INT_PTR Reserved51_4; + INT_PTR Reserved51_5; } MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; typedef struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE; @@ -278,6 +331,15 @@ typedef struct unsigned char Unused : 3; } INTERPRETER_OPT_FLAGS2, *PINTERPRETER_OPT_FLAGS2; +typedef struct _NDR_CORRELATION_FLAGS +{ + unsigned char Early : 1; + unsigned char Split : 1; + unsigned char IsIidIs : 1; + unsigned char DontCheck : 1; + unsigned char Unused : 4; +} NDR_CORRELATION_FLAGS; + #define FC_ALLOCATE_ALL_NODES 0x01 #define FC_DONT_FREE 0x02 #define FC_ALLOCED_ON_STACK 0x03 @@ -341,117 +403,123 @@ typedef enum _NDR_PHASE NDR_PHASE_FREE } NDR_PHASE; +#define FC_NORMAL_CONFORMANCE 0x00 +#define FC_POINTER_CONFORMANCE 0x10 +#define FC_TOP_LEVEL_CONFORMANCE 0x20 +#define FC_CONSTANT_CONFORMANCE 0x40 +#define FC_TOP_LEVEL_MULTID_CONFORMANCE 0x80 + /* Type Format Strings: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379093/ */ -#define FC_ZERO 0x00 -#define FC_BYTE 0x01 -#define FC_CHAR 0x02 -#define FC_SMALL 0x03 -#define FC_USMALL 0x04 -#define FC_WCHAR 0x05 -#define FC_SHORT 0x06 -#define FC_USHORT 0x07 -#define FC_LONG 0x08 -#define FC_ULONG 0x09 -#define FC_FLOAT 0x0A -#define FC_HYPER 0x0B -#define FC_DOUBLE 0x0C -#define FC_ENUM16 0x0D -#define FC_ENUM32 0x0E -#define FC_IGNORE 0x0F -#define FC_ERROR_STATUS_T 0x10 -#define FC_RP 0x11 -#define FC_UP 0x12 -#define FC_OP 0x13 -#define FC_FP 0x14 -#define FC_STRUCT 0x15 -#define FC_PSTRUCT 0x16 -#define FC_CSTRUCT 0x17 -#define FC_CPSTRUCT 0x18 -#define FC_CVSTRUCT 0x19 -#define FC_BOGUS_STRUCT 0x1A -#define FC_CARRAY 0x1B -#define FC_CVARRAY 0x1C -#define FC_SMFARRAY 0x1D -#define FC_LGFARRAY 0x1E -#define FC_SMVARRAY 0x1F -#define FC_LGVARRAY 0x20 -#define FC_BOGUS_ARRAY 0x21 -#define FC_C_CSTRING 0x22 -#define FC_C_BSTRING 0x23 -#define FC_C_SSTRING 0x24 -#define FC_C_WSTRING 0x25 -#define FC_CSTRING 0x26 -#define FC_BSTRING 0x27 -#define FC_SSTRING 0x28 -#define FC_WSTRING 0x29 -#define FC_ENCAPSULATED_UNION 0x2A -#define FC_NON_ENCAPSULATED_UNION 0x2B -#define FC_BYTE_COUNT_POINTER 0x2C -#define FC_TRANSMIT_AS 0x2D -#define FC_REPRESENT_AS 0x2E -#define FC_IP 0x2F -#define FC_BIND_CONTEXT 0x30 -#define FC_BIND_GENERIC 0x31 -#define FC_BIND_PRIMITIVE 0x32 -#define FC_AUTO_HANDLE 0x33 -#define FC_CALLBACK_HANDLE 0x34 -#define FC_UNUSED1 0x35 -#define FC_POINTER 0x36 -#define FC_ALIGNM2 0x37 -#define FC_ALIGNM4 0x38 -#define FC_ALIGNM8 0x39 -#define FC_UNUSED2 0x3A -#define FC_UNUSED3 0x3B -#define FC_UNUSED4 0x3C -#define FC_STRUCTPAD1 0x3D -#define FC_STRUCTPAD2 0x3E -#define FC_STRUCTPAD3 0x3F -#define FC_STRUCTPAD4 0x40 -#define FC_STRUCTPAD5 0x41 -#define FC_STRUCTPAD6 0x42 -#define FC_STRUCTPAD7 0x43 -#define FC_STRING_SIZED 0x44 -#define FC_UNUSED5 0x45 -#define FC_NO_REPEAT 0x46 -#define FC_FIXED_REPEAT 0x47 -#define FC_VARIABLE_REPEAT 0x48 -#define FC_FIXED_OFFSET 0x49 -#define FC_VARIABLE_OFFSET 0x4A -#define FC_PP 0x4B -#define FC_EMBEDDED_COMPLEX 0x4C -#define FC_IN_PARAM 0x4D -#define FC_IN_PARAM_BASETYPE 0x4E -#define FC_IN_PARAM_NO_FREE_INST 0x4F -#define FC_IN_OUT_PARAM 0x50 -#define FC_OUT_PARAM 0x51 -#define FC_RETURN_PARAM 0x52 -#define FC_RETURN_PARAM_BASETYPE 0x53 -#define FC_DEREFERENCE 0x54 -#define FC_DIV_2 0x55 -#define FC_MULT_2 0x56 -#define FC_ADD_1 0x57 -#define FC_SUB_1 0x58 -#define FC_CALLBACK 0x59 -#define FC_CONSTANT_IID 0x5A -#define FC_END 0x5B -#define FC_PAD 0x5C -#define FC_SPLIT_DEREFERENCE 0x74 -#define FC_SPLIT_DIV_2 0x75 -#define FC_SPLIT_MULT_2 0x76 -#define FC_SPLIT_ADD_1 0x77 -#define FC_SPLIT_SUB_1 0x78 -#define FC_SPLIT_CALLBACK 0x79 -#define FC_HARD_STRUCT 0xB1 -#define FC_TRANSMIT_AS_PTR 0xB2 -#define FC_REPRESENT_AS_PTR 0xB3 -#define FC_USER_MARSHAL 0xB4 -#define FC_PIPE 0xB5 -#define FC_BLKHOLE 0xB6 -#define FC_RANGE 0xB7 -#define FC_INT3264 0xB8 -#define FC_UINT3264 0xB9 -#define FC_END_OF_UNIVERSE 0xBA +#define FC_ZERO 0x00 +#define FC_BYTE 0x01 +#define FC_CHAR 0x02 +#define FC_SMALL 0x03 +#define FC_USMALL 0x04 +#define FC_WCHAR 0x05 +#define FC_SHORT 0x06 +#define FC_USHORT 0x07 +#define FC_LONG 0x08 +#define FC_ULONG 0x09 +#define FC_FLOAT 0x0A +#define FC_HYPER 0x0B +#define FC_DOUBLE 0x0C +#define FC_ENUM16 0x0D +#define FC_ENUM32 0x0E +#define FC_IGNORE 0x0F +#define FC_ERROR_STATUS_T 0x10 +#define FC_RP 0x11 +#define FC_UP 0x12 +#define FC_OP 0x13 +#define FC_FP 0x14 +#define FC_STRUCT 0x15 +#define FC_PSTRUCT 0x16 +#define FC_CSTRUCT 0x17 +#define FC_CPSTRUCT 0x18 +#define FC_CVSTRUCT 0x19 +#define FC_BOGUS_STRUCT 0x1A +#define FC_CARRAY 0x1B +#define FC_CVARRAY 0x1C +#define FC_SMFARRAY 0x1D +#define FC_LGFARRAY 0x1E +#define FC_SMVARRAY 0x1F +#define FC_LGVARRAY 0x20 +#define FC_BOGUS_ARRAY 0x21 +#define FC_C_CSTRING 0x22 +#define FC_C_BSTRING 0x23 +#define FC_C_SSTRING 0x24 +#define FC_C_WSTRING 0x25 +#define FC_CSTRING 0x26 +#define FC_BSTRING 0x27 +#define FC_SSTRING 0x28 +#define FC_WSTRING 0x29 +#define FC_ENCAPSULATED_UNION 0x2A +#define FC_NON_ENCAPSULATED_UNION 0x2B +#define FC_BYTE_COUNT_POINTER 0x2C +#define FC_TRANSMIT_AS 0x2D +#define FC_REPRESENT_AS 0x2E +#define FC_IP 0x2F +#define FC_BIND_CONTEXT 0x30 +#define FC_BIND_GENERIC 0x31 +#define FC_BIND_PRIMITIVE 0x32 +#define FC_AUTO_HANDLE 0x33 +#define FC_CALLBACK_HANDLE 0x34 +#define FC_UNUSED1 0x35 +#define FC_POINTER 0x36 +#define FC_ALIGNM2 0x37 +#define FC_ALIGNM4 0x38 +#define FC_ALIGNM8 0x39 +#define FC_UNUSED2 0x3A +#define FC_UNUSED3 0x3B +#define FC_UNUSED4 0x3C +#define FC_STRUCTPAD1 0x3D +#define FC_STRUCTPAD2 0x3E +#define FC_STRUCTPAD3 0x3F +#define FC_STRUCTPAD4 0x40 +#define FC_STRUCTPAD5 0x41 +#define FC_STRUCTPAD6 0x42 +#define FC_STRUCTPAD7 0x43 +#define FC_STRING_SIZED 0x44 +#define FC_UNUSED5 0x45 +#define FC_NO_REPEAT 0x46 +#define FC_FIXED_REPEAT 0x47 +#define FC_VARIABLE_REPEAT 0x48 +#define FC_FIXED_OFFSET 0x49 +#define FC_VARIABLE_OFFSET 0x4A +#define FC_PP 0x4B +#define FC_EMBEDDED_COMPLEX 0x4C +#define FC_IN_PARAM 0x4D +#define FC_IN_PARAM_BASETYPE 0x4E +#define FC_IN_PARAM_NO_FREE_INST 0x4F +#define FC_IN_OUT_PARAM 0x50 +#define FC_OUT_PARAM 0x51 +#define FC_RETURN_PARAM 0x52 +#define FC_RETURN_PARAM_BASETYPE 0x53 +#define FC_DEREFERENCE 0x54 +#define FC_DIV_2 0x55 +#define FC_MULT_2 0x56 +#define FC_ADD_1 0x57 +#define FC_SUB_1 0x58 +#define FC_CALLBACK 0x59 +#define FC_CONSTANT_IID 0x5A +#define FC_END 0x5B +#define FC_PAD 0x5C +#define FC_SPLIT_DEREFERENCE 0x74 +#define FC_SPLIT_DIV_2 0x75 +#define FC_SPLIT_MULT_2 0x76 +#define FC_SPLIT_ADD_1 0x77 +#define FC_SPLIT_SUB_1 0x78 +#define FC_SPLIT_CALLBACK 0x79 +#define FC_HARD_STRUCT 0xB1 +#define FC_TRANSMIT_AS_PTR 0xB2 +#define FC_REPRESENT_AS_PTR 0xB3 +#define FC_USER_MARSHAL 0xB4 +#define FC_PIPE 0xB5 +#define FC_BLKHOLE 0xB6 +#define FC_RANGE 0xB7 +#define FC_INT3264 0xB8 +#define FC_UINT3264 0xB9 +#define FC_END_OF_UNIVERSE 0xBA #define NdrFcShort(s) (byte)(s & 0xFF), (byte)(s >> 8) From a078c82905df8d2e8a414811efd6a7b18442003c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 3 May 2012 16:38:48 -0400 Subject: [PATCH 39/47] libfreerdp-core: start implementing Ndrp* private helpers --- libfreerdp-core/ndr.c | 670 ++++++++++++++++++++++++++++++++---------- 1 file changed, 511 insertions(+), 159 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index 0c8d0b472..eb1e7530d 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -577,16 +577,361 @@ const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = NULL, /* FC_PAD */ }; -static void AlignLength(unsigned long* length, unsigned int alignment) +char SimpleTypeAlignment[] = +{ + 0, /* FC_ZERO */ + 0, /* FC_BYTE */ + 0, /* FC_CHAR */ + 0, /* FC_SMALL */ + 0, /* FC_USMALL */ + 0, /* FC_WCHAR */ + 0, /* FC_SHORT */ + 0, /* FC_USHORT */ + 0, /* FC_LONG */ + 0, /* FC_ULONG */ + 0, /* FC_FLOAT */ + 0, /* FC_HYPER */ + 0, /* FC_DOUBLE */ + 0, /* FC_ENUM16 */ + 0, /* FC_ENUM32 */ + 0, /* FC_IGNORE */ + 0, /* FC_ERROR_STATUS_T */ +}; + +char SimpleTypeBufferSize[] = +{ + 0, /* FC_ZERO */ + 0, /* FC_BYTE */ + 0, /* FC_CHAR */ + 0, /* FC_SMALL */ + 0, /* FC_USMALL */ + 0, /* FC_WCHAR */ + 0, /* FC_SHORT */ + 0, /* FC_USHORT */ + 0, /* FC_LONG */ + 0, /* FC_ULONG */ + 0, /* FC_FLOAT */ + 0, /* FC_HYPER */ + 0, /* FC_DOUBLE */ + 0, /* FC_ENUM16 */ + 0, /* FC_ENUM32 */ + 0, /* FC_IGNORE */ + 0, /* FC_ERROR_STATUS_T */ +}; + +char SimpleTypeMemorySize[] = +{ + 0, /* FC_ZERO */ + 0, /* FC_BYTE */ + 0, /* FC_CHAR */ + 0, /* FC_SMALL */ + 0, /* FC_USMALL */ + 0, /* FC_WCHAR */ + 0, /* FC_SHORT */ + 0, /* FC_USHORT */ + 0, /* FC_LONG */ + 0, /* FC_ULONG */ + 0, /* FC_FLOAT */ + 0, /* FC_HYPER */ + 0, /* FC_DOUBLE */ + 0, /* FC_ENUM16 */ + 0, /* FC_ENUM32 */ + 0, /* FC_IGNORE */ + 0, /* FC_ERROR_STATUS_T */ +}; + +int NdrTypeFlags[] = +{ + 0, /* FC_ZERO */ + 0, /* FC_BYTE */ + 0, /* FC_CHAR */ + 0, /* FC_SMALL */ + 0, /* FC_USMALL */ + 0, /* FC_WCHAR */ + 0, /* FC_SHORT */ + 0, /* FC_USHORT */ + 0, /* FC_LONG */ + 0, /* FC_ULONG */ + 0, /* FC_FLOAT */ + 0, /* FC_HYPER */ + 0, /* FC_DOUBLE */ + 0, /* FC_ENUM16 */ + 0, /* FC_ENUM32 */ + 0, /* FC_IGNORE */ + 0, /* FC_ERROR_STATUS_T */ +}; + +static void NdrpAlignLength(unsigned long* length, unsigned int alignment) { *length = (*length + alignment - 1) & ~(alignment - 1); } -static void IncrementLength(unsigned long* length, unsigned int size) +static void NdrpIncrementLength(unsigned long* length, unsigned int size) { *length += size; } +char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar) +{ + return SimpleTypeAlignment[FormatChar]; +} + +char NdrGetSimpleTypeBufferSize(unsigned char FormatChar) +{ + return SimpleTypeAlignment[FormatChar]; +} + +char NdrGetSimpleTypeMemorySize(unsigned char FormatChar) +{ + return SimpleTypeMemorySize[FormatChar]; +} + +int NdrGetTypeFlags(unsigned char FormatChar) +{ + return NdrTypeFlags[FormatChar]; +} + +/** + * Pointer Layout: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374376/ + * + * pointer_layout<>: + * + * FC_PP + * FC_PAD + * { pointer_instance_layout<> }* + * FC_END + * + * pointer_instance<8>: + * + * offset_to_pointer_in_memory<2> + * offset_to_pointer_in_buffer<2> + * pointer_description<4> + * + */ + +PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat) +{ + pFormat += 2; + + while (*pFormat != FC_END) + { + if (*pFormat == FC_NO_REPEAT) + { + /** + * FC_NO_REPEAT + * FC_PAD + * pointer_instance<8> + */ + + pFormat += 10; + } + else if (*pFormat == FC_FIXED_REPEAT) + { + unsigned short number_of_pointers; + + /** + * FC_FIXED_REPEAT + * FC_PAD + * iterations<2> + * increment<2> + * offset_to_array<2> + * number_of_pointers<2> + * { pointer_instance<8> }* + */ + + pFormat += 8; + number_of_pointers = *(unsigned short*) pFormat; + pFormat += 2 + (number_of_pointers * 8); + } + else if (*pFormat == FC_VARIABLE_REPEAT) + { + unsigned short number_of_pointers; + + /** + * FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET) + * FC_PAD ?! + * increment<2> + * offset_to_array<2> + * number_of_pointers<2> + * { pointer_instance<8> }* + */ + + pFormat += 6; + number_of_pointers = *(unsigned short*) pFormat; + pFormat += 2 + (number_of_pointers * 8); + } + else + { + printf("error: NdrpSkipPointerLayout unexpected 0x%02X\n", *pFormat); + break; + } + } + + return pFormat + 1; +} + +/* + * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/ + * + * correlation_type<1> + * correlation_operator<1> + * offset<2> + * [robust_flags<2>] + * + */ + +PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount) +{ + LPVOID ptr = NULL; + ULONG_PTR data = 0; + unsigned char type; + unsigned short offset; + unsigned char conformance; + unsigned char correlation_type; + unsigned char correlation_operator; + + correlation_type = pFormat[0]; + type = correlation_type & 0x0F; + conformance = correlation_type & 0xF0; + + correlation_operator = pFormat[1]; + offset = *(unsigned short*) & pFormat[2]; + + if (conformance == FC_NORMAL_CONFORMANCE) + { + ptr = pMemory; + } + else if (conformance == FC_POINTER_CONFORMANCE) + { + ptr = pStubMsg->Memory; + } + else if (conformance == FC_TOP_LEVEL_CONFORMANCE) + { + ptr = pStubMsg->StackTop; + } + else if (conformance == FC_CONSTANT_CONFORMANCE ) + { + data = offset | ((DWORD) pFormat[1] << 16); + *pCount = data; + } + else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE) + { + if (pStubMsg->StackTop) + ptr = pStubMsg->StackTop; + } + + switch (correlation_operator) + { + case FC_DEREFERENCE: + ptr = *(LPVOID*)((char*) ptr + offset); + break; + + case FC_DIV_2: + ptr = (char*) ptr + offset; + break; + + case FC_MULT_2: + ptr = (char*) ptr + offset; + break; + + case FC_SUB_1: + ptr = (char*) ptr + offset; + break; + + case FC_ADD_1: + ptr = (char*) ptr + offset; + break; + + case FC_CALLBACK: + { + printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n"); + } + break; + } + + switch (type) + { + case FC_LONG: + data = *(LONG*) ptr; + break; + + case FC_ULONG: + data = *(ULONG*) ptr; + break; + + case FC_SHORT: + data = *(SHORT*) ptr; + break; + + case FC_USHORT: + data = *(USHORT*) ptr; + break; + + case FC_CHAR: + case FC_SMALL: + data = *(CHAR*) ptr; + break; + + case FC_BYTE: + case FC_USMALL: + data = *(BYTE*) ptr; + break; + + case FC_HYPER: + data = *(ULONGLONG*) ptr; + break; + } + + switch (correlation_operator) + { + case FC_ZERO: + case FC_DEREFERENCE: + *pCount = data; + break; + + case FC_DIV_2: + *pCount = data / 1; + break; + + case FC_MULT_2: + *pCount = data * 1; + break; + + case FC_SUB_1: + *pCount = data - 1; + break; + + case FC_ADD_1: + *pCount = data + 1; + break; + + case FC_CALLBACK: + break; + } + + if (pStubMsg->fHasNewCorrDesc) + pFormat += 6; + else + pFormat += 4; + + return pFormat; +} + +PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount); +} + +PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + ULONG_PTR ActualCount = pStubMsg->ActualCount; + + pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount); + pStubMsg->ActualCount = (ULONG) ActualCount; + + return pFormat; +} + void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { switch (*pFormat) @@ -595,15 +940,15 @@ void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory case FC_CHAR: case FC_SMALL: case FC_USMALL: - IncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE)); break; case FC_WCHAR: case FC_SHORT: case FC_USHORT: case FC_ENUM16: - AlignLength(&(pStubMsg->BufferLength), sizeof(USHORT)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT)); break; case FC_LONG: @@ -611,28 +956,28 @@ void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory case FC_ENUM32: case FC_INT3264: case FC_UINT3264: - AlignLength(&(pStubMsg->BufferLength), sizeof(ULONG)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG)); break; case FC_FLOAT: - AlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); break; case FC_DOUBLE: - AlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); break; case FC_HYPER: - AlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); break; case FC_ERROR_STATUS_T: - AlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); - IncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); break; case FC_IGNORE: @@ -642,21 +987,21 @@ void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory /* Pointers: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802750/ */ -void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +/** + * pointer_type<1> + * pointer_attributes<1> + * simple_type<1> + * FC_PAD + */ + +/** + * pointer_type<1> + * pointer_attributes<1> + * offset_to_complex_description<2> + */ + +void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg) { - /** - * pointer_type<1> - * pointer_attributes<1> - * simple_type<1> - * FC_PAD - */ - - /** - * pointer_type<1> - * pointer_attributes<1> - * offset_to_complex_description<2> - */ - unsigned char type; unsigned char attributes; PFORMAT_STRING pNextFormat; @@ -666,12 +1011,6 @@ void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, P attributes = pFormat[1]; pFormat += 2; - if (type != FC_RP) - { - AlignLength((&pStubMsg->BufferLength), 4); - IncrementLength((&pStubMsg->BufferLength), 4); - } - if (attributes & FC_SIMPLE_POINTER) pNextFormat = pFormat; else @@ -704,25 +1043,118 @@ void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, P pfnSizeRoutine(pStubMsg, pMemory, pNextFormat); } +PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory) +{ + return 0; +} + +PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned char* Memory; + char PointerLengthSet; + PFORMAT_STRING pFormatCopy; + unsigned long BufferLength; + unsigned long BufferLengthCopy; + unsigned long PointerLength; + unsigned char* pMemoryPtr = NULL; + + pFormatCopy = pFormat; + + if (!pStubMsg->IgnoreEmbeddedPointers) + { + PointerLength = pStubMsg->PointerLength; + PointerLengthSet = (PointerLength != 0); + + if (PointerLengthSet) + { + BufferLength = pStubMsg->BufferLength; + pStubMsg->PointerLength = 0; + BufferLengthCopy = BufferLength; + pStubMsg->BufferLength = PointerLength; + } + + MaxCount = pStubMsg->MaxCount; + Offset = pStubMsg->Offset; + Memory = pStubMsg->Memory; + pStubMsg->Memory = pMemory; + pFormat = pFormatCopy + 2; + + while (*pFormat != FC_END) + { + if (*pFormat == FC_NO_REPEAT) + { + NdrpPointerBufferSize(&pMemory[pFormat[2]], &pFormat[6], pStubMsg); + pFormat += 10; + } + + pStubMsg->Offset = Offset; + pStubMsg->MaxCount = MaxCount; + + NdrpEmbeddedRepeatPointerBufferSize(pStubMsg, pMemory, pFormat, &pMemoryPtr); + } + + pStubMsg->Memory = Memory; + + if (PointerLengthSet) + { + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = BufferLengthCopy; + } + } + + return pFormat; +} + +void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + if (*pFormat != FC_RP) + { + NdrpAlignLength((&pStubMsg->BufferLength), 4); + NdrpIncrementLength((&pStubMsg->BufferLength), 4); + } + + NdrpPointerBufferSize(pMemory, pFormat, pStubMsg); +} + /* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */ void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { /** - * FC_STRUCT alignment<1> + * FC_STRUCT + * alignment<1> * memory_size<2> * member_layout<> * FC_END */ /** - * FC_PSTRUCT alignment<1> + * FC_PSTRUCT + * alignment<1> * memory_size<2> * pointer_layout<> * member_layout<> * FC_END */ + unsigned char type; + unsigned char alignment; + unsigned short memory_size; + + type = pFormat[0]; + alignment = pFormat[1] + 1; + memory_size = *(unsigned short*) &pFormat[2]; + + NdrpAlignLength(&(pStubMsg->BufferLength), alignment); + NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size); + + pFormat += 4; + + if (*pFormat == FC_PSTRUCT) + NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + printf("warning: NdrSimpleStructBufferSize unimplemented\n"); } @@ -824,15 +1256,15 @@ ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFo break; case FC_ALIGNM2: - AlignLength(&size, 2); + NdrpAlignLength(&size, 2); break; case FC_ALIGNM4: - AlignLength(&size, 4); + NdrpAlignLength(&size, 4); break; case FC_ALIGNM8: - AlignLength(&size, 8); + NdrpAlignLength(&size, 8); break; case FC_STRUCTPAD1: @@ -876,6 +1308,11 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem * [pointer_layout<>] */ + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned long ActualCount; + unsigned char* pMemoryCopy; + unsigned char type; unsigned char alignment; unsigned short memory_size; @@ -885,6 +1322,7 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem unsigned short offset_to_conformant_array_description; type = pFormat[0]; + pMemoryCopy = pMemory; pointer_layout = conformant_array_description = NULL; if (type != FC_BOGUS_STRUCT) @@ -896,7 +1334,7 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem alignment = pFormat[1] + 1; memory_size = *(unsigned short*) &pFormat[2]; - AlignLength(&(pStubMsg->BufferLength), alignment); + NdrpAlignLength(&(pStubMsg->BufferLength), alignment); if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) { @@ -929,128 +1367,42 @@ void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem if (conformant_array_description) { - ULONG size = NdrComplexStructMemberSize(pStubMsg, pFormat); + ULONG size; + unsigned char array_type; + + array_type = conformant_array_description[0]; + size = NdrComplexStructMemberSize(pStubMsg, pFormat); + + printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); + + NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description); + NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description); + + MaxCount = pStubMsg->MaxCount; + ActualCount = pStubMsg->ActualCount; + Offset = pStubMsg->Offset; } - printf("warning: NdrComplexStructBufferSize unimplemented\n"); -} - -/* - * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/ - * - * correlation_type<1> - * correlation_operator<1> - * offset<2> - * [robust_flags<2>] - * - */ - -void NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - LPVOID ptr = NULL; - ULONG_PTR data = 0; - unsigned char type; - unsigned short offset; - unsigned char conformance; - unsigned char correlation_type; - unsigned char correlation_operator; - - correlation_type = pFormat[0]; - type = correlation_type & 0x0F; - conformance = correlation_type & 0xF0; - - correlation_operator = pFormat[1]; - offset = *(unsigned short*) & pFormat[2]; - - if (conformance == FC_NORMAL_CONFORMANCE) + if (conformant_array_description) { - ptr = pMemory; + unsigned char array_type; + + array_type = conformant_array_description[0]; + + pStubMsg->MaxCount = MaxCount; + pStubMsg->ActualCount = ActualCount; + pStubMsg->Offset = Offset; + + printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); } - else if (conformance == FC_POINTER_CONFORMANCE) + + pStubMsg->Memory = pMemoryCopy; + + if (pStubMsg->PointerLength > 0) { - ptr = pStubMsg->Memory; + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; } - else if (conformance == FC_TOP_LEVEL_CONFORMANCE) - { - ptr = pStubMsg->StackTop; - } - else if (conformance == FC_CONSTANT_CONFORMANCE ) - { - data = offset | ((DWORD) pFormat[1] << 16); - pStubMsg->MaxCount = data; - } - else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE) - { - if (pStubMsg->StackTop) - ptr = pStubMsg->StackTop; - } - - switch (correlation_operator) - { - case FC_DEREFERENCE: - ptr = *(LPVOID*)((char*) ptr + offset); - break; - - case FC_DIV_2: - ptr = (char*) ptr + offset; - break; - - case FC_MULT_2: - ptr = (char*) ptr + offset; - break; - - case FC_SUB_1: - ptr = (char*) ptr + offset; - break; - - case FC_ADD_1: - ptr = (char*) ptr + offset; - break; - - case FC_CALLBACK: - { - printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n"); - } - break; - } - - switch (type) - { - case FC_LONG: - data = *(LONG*) ptr; - break; - - case FC_ULONG: - data = *(ULONG*) ptr; - break; - - case FC_SHORT: - data = *(SHORT*) ptr; - break; - - case FC_USHORT: - data = *(USHORT*) ptr; - break; - - case FC_CHAR: - case FC_SMALL: - data = *(CHAR*) ptr; - break; - - case FC_BYTE: - case FC_USMALL: - data = *(BYTE*) ptr; - break; - - case FC_HYPER: - data = *(ULONGLONG*) ptr; - break; - } -} - -void NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - } void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) @@ -1226,8 +1578,8 @@ void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem * param_num<1> */ - AlignLength(&(pStubMsg->BufferLength), 4); - IncrementLength(&(pStubMsg->BufferLength), 20); + NdrpAlignLength(&(pStubMsg->BufferLength), 4); + NdrpIncrementLength(&(pStubMsg->BufferLength), 20); } } From 62a76155350b7c2fd1f68477d07a09ffe4790d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 3 May 2012 22:04:14 -0400 Subject: [PATCH 40/47] libfreerdp-core: implement embedded pointer sizing --- libfreerdp-core/ndr.c | 216 ++++++++++++++++++++++++++++-------------- libfreerdp-core/rpc.c | 5 + libfreerdp-core/rpc.h | 4 + 3 files changed, 155 insertions(+), 70 deletions(-) diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index eb1e7530d..aab7addc9 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -579,86 +579,82 @@ const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = char SimpleTypeAlignment[] = { - 0, /* FC_ZERO */ - 0, /* FC_BYTE */ - 0, /* FC_CHAR */ - 0, /* FC_SMALL */ - 0, /* FC_USMALL */ - 0, /* FC_WCHAR */ - 0, /* FC_SHORT */ - 0, /* FC_USHORT */ - 0, /* FC_LONG */ - 0, /* FC_ULONG */ - 0, /* FC_FLOAT */ - 0, /* FC_HYPER */ - 0, /* FC_DOUBLE */ - 0, /* FC_ENUM16 */ - 0, /* FC_ENUM32 */ - 0, /* FC_IGNORE */ - 0, /* FC_ERROR_STATUS_T */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x01, 0x03, 0x03, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; char SimpleTypeBufferSize[] = { - 0, /* FC_ZERO */ - 0, /* FC_BYTE */ - 0, /* FC_CHAR */ - 0, /* FC_SMALL */ - 0, /* FC_USMALL */ - 0, /* FC_WCHAR */ - 0, /* FC_SHORT */ - 0, /* FC_USHORT */ - 0, /* FC_LONG */ - 0, /* FC_ULONG */ - 0, /* FC_FLOAT */ - 0, /* FC_HYPER */ - 0, /* FC_DOUBLE */ - 0, /* FC_ENUM16 */ - 0, /* FC_ENUM32 */ - 0, /* FC_IGNORE */ - 0, /* FC_ERROR_STATUS_T */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; char SimpleTypeMemorySize[] = { - 0, /* FC_ZERO */ - 0, /* FC_BYTE */ - 0, /* FC_CHAR */ - 0, /* FC_SMALL */ - 0, /* FC_USMALL */ - 0, /* FC_WCHAR */ - 0, /* FC_SHORT */ - 0, /* FC_USHORT */ - 0, /* FC_LONG */ - 0, /* FC_ULONG */ - 0, /* FC_FLOAT */ - 0, /* FC_HYPER */ - 0, /* FC_DOUBLE */ - 0, /* FC_ENUM16 */ - 0, /* FC_ENUM32 */ - 0, /* FC_IGNORE */ - 0, /* FC_ERROR_STATUS_T */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, }; -int NdrTypeFlags[] = +char NdrTypeFlags[] = { - 0, /* FC_ZERO */ - 0, /* FC_BYTE */ - 0, /* FC_CHAR */ - 0, /* FC_SMALL */ - 0, /* FC_USMALL */ - 0, /* FC_WCHAR */ - 0, /* FC_SHORT */ - 0, /* FC_USHORT */ - 0, /* FC_LONG */ - 0, /* FC_ULONG */ - 0, /* FC_FLOAT */ - 0, /* FC_HYPER */ - 0, /* FC_DOUBLE */ - 0, /* FC_ENUM16 */ - 0, /* FC_ENUM32 */ - 0, /* FC_IGNORE */ - 0, /* FC_ERROR_STATUS_T */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x02, 0x02, 0x02, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xA0, 0xA0, 0x00, 0xC0, 0xC0, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, + 0x03, 0x10, 0x01, 0x03, 0x2C, 0x01, 0x03, 0xE0, 0x90, 0x90, 0x8B, 0x57, 0x83, 0xE7, 0x6C, 0x01, + 0x09, 0x70, 0x3B, 0x86, 0x00, 0x0F, 0x01, 0x5A, 0x00, 0x80, 0x00, 0x30, 0x8D, 0x30, 0x84, 0x00, + 0x48, 0x6A, 0x00, 0x6A, 0x01, 0x06, 0xFF, 0x08, 0x5D, 0x90, 0x7D, 0x7D, 0x0F, 0x67, 0xBD, 0xAD, + 0xAD, 0xAD, 0x9B, 0xBA, 0x9B, 0x9B, 0x0D, 0xB9, 0xAD, 0x19, 0x19, 0xBA, 0xDB, 0x09, 0x86, 0xB1, }; static void NdrpAlignLength(unsigned long* length, unsigned int alignment) @@ -1045,7 +1041,87 @@ void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory) { - return 0; + ULONG_PTR MaxCount; + unsigned char* Memory; + unsigned char* MemoryCopy; + unsigned char* MemoryPointer; + PFORMAT_STRING pFormatNext; + PFORMAT_STRING pFormatPointers; + unsigned short increment; + unsigned short pointer_count; + unsigned short offset_to_array; + unsigned short number_of_pointers; + + Memory = pStubMsg->Memory; + MemoryCopy = pStubMsg->Memory; + + if (*pFormat == FC_FIXED_REPEAT) + { + pFormat += 2; + MaxCount = *(unsigned short*) pFormat; + } + else + { + if (*pFormat != FC_VARIABLE_REPEAT) + { + RpcRaiseException(1766); + return pFormat; + } + + MaxCount = pStubMsg->MaxCount; + + if (pFormat[1] == FC_VARIABLE_OFFSET) + { + pMemory += pStubMsg->Offset * *((unsigned short*) &pFormat[1]); + } + } + + pFormat += 2; + increment = *(unsigned short*) pFormat; + + pFormat += 2; + offset_to_array = *(unsigned short*) pFormat; + pStubMsg->Memory = Memory + offset_to_array; + + pFormat += 2; + number_of_pointers = *(unsigned short*) pFormat; + + pFormat += 2; + + pFormatPointers = pFormat; + + if (MaxCount) + { + do + { + MaxCount--; + pFormatNext = pFormatPointers; + pointer_count = number_of_pointers; + + if (number_of_pointers) + { + do + { + pointer_count--; + MemoryPointer = &pMemory[*(unsigned short*) pFormatNext]; + NdrpPointerBufferSize(MemoryPointer, pFormatNext + 4, pStubMsg); + pFormatNext += 8; + } + while (pointer_count); + } + + pMemory += increment; + pStubMsg->Memory += increment; + } + while (MaxCount); + + Memory = MemoryCopy; + } + + pFormat = pFormatPointers + (number_of_pointers * 8); + pStubMsg->Memory = Memory; + + return pFormat; } PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 760b4db4e..6933b8682 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -29,6 +29,11 @@ #include "rpc.h" +void RpcRaiseException(RPC_STATUS exception) +{ + printf("RpcRaiseException: 0x%08X\n", exception); +} + #define NTLM_PACKAGE_NAME _T("NTLM") boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password) diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 40acbca4e..a829c6f09 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -42,6 +42,8 @@ typedef struct rdp_ntlm_http rdpNtlmHttp; #include #include +typedef long RPC_STATUS; + struct _rpc_pdu_header { uint8 rpc_vers; @@ -664,6 +666,8 @@ struct rdp_rpc RpcVirtualConnection* VirtualConnection; }; +void RpcRaiseException(RPC_STATUS exception); + boolean ntlm_authenticate(rdpNtlm* ntlm); boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password); From 95b6e2e04be4f993ca2c18a7df6e2cba0d70d62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 4 May 2012 17:23:26 -0400 Subject: [PATCH 41/47] libfreerdp-core: fix compilation on windows --- include/freerdp/sspi/sspi.h | 8 ++++---- include/freerdp/wtypes.h | 15 ++++++++------- libfreerdp-core/http.c | 6 ++++++ libfreerdp-core/ndr.c | 5 ++--- libfreerdp-core/tsg.c | 3 ++- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/include/freerdp/sspi/sspi.h b/include/freerdp/sspi/sspi.h index 0789e249d..958a1b16e 100644 --- a/include/freerdp/sspi/sspi.h +++ b/include/freerdp/sspi/sspi.h @@ -953,10 +953,10 @@ FREERDP_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSe /* Custom API */ -void sspi_GlobalInit(); -void sspi_GlobalFinish(); +FREERDP_API void sspi_GlobalInit(); +FREERDP_API void sspi_GlobalFinish(); -void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size); -void sspi_SecBufferFree(PSecBuffer SecBuffer); +FREERDP_API void sspi_SecBufferAlloc(PSecBuffer SecBuffer, size_t size); +FREERDP_API void sspi_SecBufferFree(PSecBuffer SecBuffer); #endif /* FREERDP_SSPI_H */ diff --git a/include/freerdp/wtypes.h b/include/freerdp/wtypes.h index 0f6655934..f544a2438 100644 --- a/include/freerdp/wtypes.h +++ b/include/freerdp/wtypes.h @@ -42,12 +42,10 @@ typedef int BOOL, *PBOOL, *LPBOOL; typedef unsigned char BYTE, *PBYTE, *LPBYTE; -typedef BYTE byte; typedef BYTE BOOLEAN, *PBOOLEAN; typedef wchar_t WCHAR, *PWCHAR; typedef WCHAR* BSTR; typedef char CHAR, *PCHAR; -typedef double DOUBLE; typedef unsigned long DWORD, *PDWORD, *LPDWORD; typedef unsigned int DWORD32; typedef unsigned __int64 DWORD64; @@ -111,11 +109,6 @@ typedef int INT_PTR; typedef unsigned int UINT_PTR; #endif -typedef void* PCONTEXT_HANDLE; -typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; - -typedef unsigned long error_status_t; - typedef struct _GUID { unsigned long Data1; @@ -181,4 +174,12 @@ typedef struct _SECURITY_DESCRIPTOR #endif +typedef BYTE byte; +typedef double DOUBLE; + +typedef void* PCONTEXT_HANDLE; +typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; + +typedef unsigned long error_status_t; + #endif /* FREERDP_WINDOWS_TYPES_H */ diff --git a/libfreerdp-core/http.c b/libfreerdp-core/http.c index 985d185ff..862cd2f20 100644 --- a/libfreerdp-core/http.c +++ b/libfreerdp-core/http.c @@ -107,9 +107,15 @@ void http_request_set_auth_param(HttpRequest* http_request, char* auth_param) http_request->AuthParam = xstrdup(auth_param); } +#ifdef _WIN32 +#define http_encode_line(_str, _fmt, ...) \ + _str = xmalloc(sprintf_s(NULL, 0, _fmt, ## __VA_ARGS__) + 1); \ + sprintf_s(_str, sprintf_s(NULL, 0, _fmt, ## __VA_ARGS__) + 1, _fmt, ## __VA_ARGS__); +#else #define http_encode_line(_str, _fmt, ...) \ _str = xmalloc(snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1); \ snprintf(_str, snprintf(NULL, 0, _fmt, ## __VA_ARGS__) + 1, _fmt, ## __VA_ARGS__); +#endif STREAM* http_request_write(HttpContext* http_context, HttpRequest* http_request) { diff --git a/libfreerdp-core/ndr.c b/libfreerdp-core/ndr.c index aab7addc9..8e05dea6f 100644 --- a/libfreerdp-core/ndr.c +++ b/libfreerdp-core/ndr.c @@ -874,7 +874,7 @@ PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem break; case FC_HYPER: - data = *(ULONGLONG*) ptr; + data = (ULONG_PTR) *(ULONGLONG*) ptr; break; } @@ -1773,7 +1773,6 @@ void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_P for (i = 0; i < numberParams; i++) { - float tmp; arg = pStubMsg->StackTop + params[i].StackOffset; fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset]; @@ -1782,7 +1781,7 @@ void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_P !(params[i].Attributes.IsSimpleRef) && ((params[i].Type.FormatChar) == FC_FLOAT) && !fpuArgs) { - tmp = *(double*) arg; + float tmp = *(double*) arg; arg = (unsigned char*) &tmp; } #endif diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index a2d6f7183..536e4a358 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -1692,6 +1692,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { uint8* data; uint32 length; + STREAM* s_p4; int status = -1; UNICONV* tsg_uniconv; rdpRpc* rpc = tsg->rpc; @@ -1829,7 +1830,7 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) memcpy(tsg_packet4 + 4, tsg->TunnelContext, 16); memcpy(tsg_packet4 + 38, &port, 2); - STREAM* s_p4 = stream_new(60 + dest_addr_unic_len + 2); + s_p4 = stream_new(60 + dest_addr_unic_len + 2); stream_write(s_p4, tsg_packet4, 48); stream_write_uint32(s_p4, (dest_addr_unic_len / 2) + 1); /* MaximumCount */ stream_write_uint32(s_p4, 0x00000000); /* Offset */ From be1e7f82915eb5f7ef07bb339ec47b37abbfe7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 4 May 2012 18:32:34 -0400 Subject: [PATCH 42/47] libwinpr-rpc: initial commit --- CMakeLists.txt | 2 ++ include/winpr/midl.h | 28 +++++++++++++++ {libfreerdp-core => include/winpr}/ndr.h | 19 ++++------ include/winpr/rpc.h | 46 ++++++++++++++++++++++++ libfreerdp-core/CMakeLists.txt | 4 +-- libfreerdp-core/rpc.c | 5 --- libfreerdp-core/rpc.h | 4 --- libfreerdp-core/tsg.c | 2 +- libfreerdp-core/tsg.h | 14 ++------ libwinpr-rpc/CMakeLists.txt | 40 +++++++++++++++++++++ libwinpr-rpc/midl.c | 33 +++++++++++++++++ {libfreerdp-core => libwinpr-rpc}/ndr.c | 16 ++------- libwinpr-rpc/rpc.c | 27 ++++++++++++++ 13 files changed, 190 insertions(+), 50 deletions(-) create mode 100644 include/winpr/midl.h rename {libfreerdp-core => include/winpr}/ndr.h (97%) create mode 100644 include/winpr/rpc.h create mode 100644 libwinpr-rpc/CMakeLists.txt create mode 100644 libwinpr-rpc/midl.c rename {libfreerdp-core => libwinpr-rpc}/ndr.c (99%) create mode 100644 libwinpr-rpc/rpc.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e5d96325..b40e367c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,8 @@ add_subdirectory(libfreerdp-channels) add_subdirectory(libfreerdp-locale) add_subdirectory(libfreerdp-core) +add_subdirectory(libwinpr-rpc) + if(NOT WIN32) add_subdirectory(channels) endif() diff --git a/include/winpr/midl.h b/include/winpr/midl.h new file mode 100644 index 000000000..75a87eb38 --- /dev/null +++ b/include/winpr/midl.h @@ -0,0 +1,28 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_MIDL_H +#define WINPR_RPC_MIDL_H + +#include + +WINPR_API void* MIDL_user_allocate(size_t cBytes); +WINPR_API void MIDL_user_free(void* p); + +#endif /* WINPR_RPC_MIDL_H */ diff --git a/libfreerdp-core/ndr.h b/include/winpr/ndr.h similarity index 97% rename from libfreerdp-core/ndr.h rename to include/winpr/ndr.h index f5fe77264..ed2446500 100644 --- a/libfreerdp-core/ndr.h +++ b/include/winpr/ndr.h @@ -1,5 +1,5 @@ /** - * FreeRDP: A Remote Desktop Protocol Implementation + * WinPR: Windows Portable Runtime * Network Data Representation (NDR) * * Copyright 2012 Marc-Andre Moreau @@ -17,17 +17,13 @@ * limitations under the License. */ -#ifndef FREERDP_CORE_NDR_H -#define FREERDP_CORE_NDR_H - -#include "rpc.h" +#ifndef WINPR_RPC_NDR_H +#define WINPR_RPC_NDR_H #include "config.h" -#include +#include #include -#include -#include #define __RPC_WIN32__ 1 #define TARGET_IS_NT50_OR_LATER 1 @@ -526,9 +522,6 @@ typedef enum _NDR_PHASE #define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \ (byte)((s & 0x00FF0000) >> 16), (byte)(s >> 24) -CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); +WINPR_API CLIENT_CALL_RETURN RPC_VAR_ENTRY NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); -void* MIDL_user_allocate(size_t cBytes); -void MIDL_user_free(void* p); - -#endif /* FREERDP_CORE_NDR_H */ +#endif /* WINPR_RPC_NDR_H */ diff --git a/include/winpr/rpc.h b/include/winpr/rpc.h new file mode 100644 index 000000000..5feadbecd --- /dev/null +++ b/include/winpr/rpc.h @@ -0,0 +1,46 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_H +#define WINPR_RPC_H + +#include +#include + +#define RPC_VAR_ENTRY __cdecl +#define WINPR_API FREERDP_API + +typedef long RPC_STATUS; + +typedef void* I_RPC_HANDLE; +typedef I_RPC_HANDLE RPC_BINDING_HANDLE; +typedef RPC_BINDING_HANDLE handle_t; + +typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE; +typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE; + +typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE; +typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE; + +void RpcRaiseException(RPC_STATUS exception); + +#include +#include + +#endif /* WINPR_RPC_H */ diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 3bc768469..6aa6da49e 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -41,8 +41,6 @@ set(LIBFREERDP_CORE_SRCS rpc.h rts.c rts.h - ndr.c - ndr.h input.c input.h license.c @@ -111,5 +109,7 @@ target_link_libraries(freerdp-core freerdp-sspi) target_link_libraries(freerdp-core freerdp-locale) target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES}) +target_link_libraries(freerdp-core winpr-rpc) + install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 6933b8682..760b4db4e 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -29,11 +29,6 @@ #include "rpc.h" -void RpcRaiseException(RPC_STATUS exception) -{ - printf("RpcRaiseException: 0x%08X\n", exception); -} - #define NTLM_PACKAGE_NAME _T("NTLM") boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password) diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index a829c6f09..40acbca4e 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -42,8 +42,6 @@ typedef struct rdp_ntlm_http rdpNtlmHttp; #include #include -typedef long RPC_STATUS; - struct _rpc_pdu_header { uint8 rpc_vers; @@ -666,8 +664,6 @@ struct rdp_rpc RpcVirtualConnection* VirtualConnection; }; -void RpcRaiseException(RPC_STATUS exception); - boolean ntlm_authenticate(rdpNtlm* ntlm); boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password); diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index 536e4a358..ffb7a7222 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -29,7 +29,7 @@ #include #include -#include "ndr.h" +#include #include "tsg.h" diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 115969f7e..9c270ae7a 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -23,8 +23,10 @@ typedef struct rdp_tsg rdpTsg; -#include "transport.h" #include "rpc.h" +#include "transport.h" + +#include #include #include @@ -43,16 +45,6 @@ struct rdp_tsg uint8 ChannelContext[16]; }; -typedef void* I_RPC_HANDLE; -typedef I_RPC_HANDLE RPC_BINDING_HANDLE; -typedef RPC_BINDING_HANDLE handle_t; - -typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE; -typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE; - -typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE; -typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE; - typedef wchar_t* RESOURCENAME; #define MAX_RESOURCE_NAMES 50 diff --git a/libwinpr-rpc/CMakeLists.txt b/libwinpr-rpc/CMakeLists.txt new file mode 100644 index 000000000..5d7a9b343 --- /dev/null +++ b/libwinpr-rpc/CMakeLists.txt @@ -0,0 +1,40 @@ +# WinPR: Windows Portable Runtime +# libwinpr-rpc cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(WINPR_RPC_SRCS + rpc.c + ndr.c + midl.c) + +add_library(winpr-rpc ${WINPR_RPC_SRCS}) + +include_directories(${OPENSSL_INCLUDE_DIR}) +include_directories(${ZLIB_INCLUDE_DIRS}) + +set_target_properties(winpr-rpc PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +if(WIN32) + target_link_libraries(winpr-rpc ws2_32) +else() + target_link_libraries(winpr-rpc ${ZLIB_LIBRARIES}) +endif() + +target_link_libraries(winpr-rpc ${OPENSSL_LIBRARIES}) + +install(TARGETS winpr-rpc DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libwinpr-rpc/midl.c b/libwinpr-rpc/midl.c new file mode 100644 index 000000000..bdd5bde5e --- /dev/null +++ b/libwinpr-rpc/midl.c @@ -0,0 +1,33 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void* MIDL_user_allocate(size_t cBytes) +{ + return (malloc(cBytes)); +} + +void MIDL_user_free(void* p) +{ + free(p); +} diff --git a/libfreerdp-core/ndr.c b/libwinpr-rpc/ndr.c similarity index 99% rename from libfreerdp-core/ndr.c rename to libwinpr-rpc/ndr.c index 8e05dea6f..b3c8f85b4 100644 --- a/libfreerdp-core/ndr.c +++ b/libwinpr-rpc/ndr.c @@ -1,5 +1,5 @@ /** - * FreeRDP: A Remote Desktop Protocol Implementation + * WinPR: Windows Portable Runtime * Network Data Representation (NDR) * * Copyright 2012 Marc-Andre Moreau @@ -17,9 +17,7 @@ * limitations under the License. */ -#include - -#include "ndr.h" +#include /** * MSRPC NDR Types Technical Overview: @@ -1976,13 +1974,3 @@ CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRIN return client_call_return; } - -void* MIDL_user_allocate(size_t cBytes) -{ - return (xmalloc(cBytes)); -} - -void MIDL_user_free(void* p) -{ - xfree(p); -} diff --git a/libwinpr-rpc/rpc.c b/libwinpr-rpc/rpc.c new file mode 100644 index 000000000..4200bb395 --- /dev/null +++ b/libwinpr-rpc/rpc.c @@ -0,0 +1,27 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +void RpcRaiseException(RPC_STATUS exception) +{ + printf("RpcRaiseException: 0x%08X\n", exception); +} From e1e3f12114539b19e5841f0282940f9158b46c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 4 May 2012 19:36:35 -0400 Subject: [PATCH 43/47] winpr: move wtypes.h and windows.h --- CMakeLists.txt | 1 + client/Windows/wfreerdp.c | 2 +- client/Windows/wfreerdp.h | 2 +- include/freerdp/crypto/crypto.h | 2 +- include/freerdp/sspi/sspi.h | 2 +- include/winpr/ndr.h | 4 +- include/winpr/rpc.h | 5 +-- include/{freerdp/utils => winpr}/windows.h | 10 ++--- include/winpr/winpr.h | 52 ++++++++++++++++++++++ include/{freerdp => winpr}/wtypes.h | 11 +++-- libfreerdp-core/extension.h | 3 +- libfreerdp-core/rpc.c | 2 +- libfreerdp-core/tcp.h | 2 +- libfreerdp-core/tsg.h | 2 +- libfreerdp-rail/window.c | 2 +- libfreerdp-utils/file.c | 2 +- libfreerdp-utils/load_plugin.c | 2 +- libfreerdp-utils/mutex.c | 2 +- libfreerdp-utils/semaphore.c | 2 +- libfreerdp-utils/sleep.c | 2 +- libfreerdp-utils/tcp.c | 2 +- libfreerdp-utils/thread.c | 2 +- libfreerdp-utils/time.c | 2 +- libfreerdp-utils/unicode.c | 2 +- libfreerdp-utils/wait_obj.c | 3 +- libwinpr-rpc/ndr.c | 2 + 26 files changed, 89 insertions(+), 36 deletions(-) rename include/{freerdp/utils => winpr}/windows.h (83%) create mode 100644 include/winpr/winpr.h rename include/{freerdp => winpr}/wtypes.h (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b40e367c6..314bf6964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 7c1d79144..4b1b97118 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -19,7 +19,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 099bd6cdc..062618019 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -22,7 +22,7 @@ #ifndef __WFREERDP_H #define __WFREERDP_H -#include +#include #include #include diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index d3c3d74ae..e3baa6079 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -21,7 +21,7 @@ #define FREERDP_CRYPTO_H /* OpenSSL includes windows.h */ -#include +#include #include #include diff --git a/include/freerdp/sspi/sspi.h b/include/freerdp/sspi/sspi.h index 958a1b16e..376d08f16 100644 --- a/include/freerdp/sspi/sspi.h +++ b/include/freerdp/sspi/sspi.h @@ -21,10 +21,10 @@ #define FREERDP_SSPI_H #include +#include #include #include -#include #ifdef _WIN32 diff --git a/include/winpr/ndr.h b/include/winpr/ndr.h index ed2446500..ed288e3a2 100644 --- a/include/winpr/ndr.h +++ b/include/winpr/ndr.h @@ -20,10 +20,8 @@ #ifndef WINPR_RPC_NDR_H #define WINPR_RPC_NDR_H -#include "config.h" - #include -#include +#include #define __RPC_WIN32__ 1 #define TARGET_IS_NT50_OR_LATER 1 diff --git a/include/winpr/rpc.h b/include/winpr/rpc.h index 5feadbecd..8be422f51 100644 --- a/include/winpr/rpc.h +++ b/include/winpr/rpc.h @@ -20,11 +20,10 @@ #ifndef WINPR_RPC_H #define WINPR_RPC_H -#include -#include +#include +#include #define RPC_VAR_ENTRY __cdecl -#define WINPR_API FREERDP_API typedef long RPC_STATUS; diff --git a/include/freerdp/utils/windows.h b/include/winpr/windows.h similarity index 83% rename from include/freerdp/utils/windows.h rename to include/winpr/windows.h index ecf95f66f..8daed265b 100644 --- a/include/freerdp/utils/windows.h +++ b/include/winpr/windows.h @@ -1,6 +1,6 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * Windows Header Utils + * WinPR: Windows Portable Runtime + * Windows Header Include Wrapper * * Copyright 2012 Marc-Andre Moreau * @@ -17,8 +17,8 @@ * limitations under the License. */ -#ifndef FREERDP_WINDOWS_UTILS_H -#define FREERDP_WINDOWS_UTILS_H +#ifndef WINPR_WINDOWS_H +#define WINPR_WINDOWS_H /* Windows header include order is important, use this instead of including windows.h directly */ @@ -34,4 +34,4 @@ #endif -#endif /* FREERDP_WINDOWS_UTILS_H */ +#endif /* WINPR_WINDOWS_H */ diff --git a/include/winpr/winpr.h b/include/winpr/winpr.h new file mode 100644 index 000000000..479b19b6e --- /dev/null +++ b/include/winpr/winpr.h @@ -0,0 +1,52 @@ +/** + * WinPR: Windows Portable Runtime + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_H +#define WINPR_H + +#include "config.h" + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef WINPR_EXPORTS + #ifdef __GNUC__ + #define WINPR_API __attribute__((dllexport)) + #else + #define WINPR_API __declspec(dllexport) + #endif + #else + #ifdef __GNUC__ + #define WINPR_API __attribute__((dllimport)) + #else + #define WINPR_API __declspec(dllimport) + #endif + #endif +#else + #if __GNUC__ >= 4 + #define WINPR_API __attribute__ ((visibility("default"))) + #else + #define WINPR_API + #endif +#endif + +#ifdef _WIN32 +#define INLINE __inline +#else +#define INLINE inline +#endif + +#endif /* WINPR_H */ diff --git a/include/freerdp/wtypes.h b/include/winpr/wtypes.h similarity index 95% rename from include/freerdp/wtypes.h rename to include/winpr/wtypes.h index f544a2438..c01e2d4df 100644 --- a/include/freerdp/wtypes.h +++ b/include/winpr/wtypes.h @@ -1,5 +1,5 @@ /** - * FreeRDP: A Remote Desktop Protocol Client + * WinPR: Windows Portable Runtime * Windows Data Types * * Copyright 2012 Marc-Andre Moreau @@ -17,15 +17,14 @@ * limitations under the License. */ -#ifndef FREERDP_WINDOWS_TYPES_H -#define FREERDP_WINDOWS_TYPES_H +#ifndef WINPR_WTYPES_H +#define WINPR_WTYPES_H /* MSDN: Windows Data Types - http://msdn.microsoft.com/en-us/library/aa383751/ */ /* [MS-DTYP]: Windows Data Types - http://msdn.microsoft.com/en-us/library/cc230273/ */ #include -#include -#include +#include #ifndef _WIN32 @@ -182,4 +181,4 @@ typedef PCONTEXT_HANDLE* PPCONTEXT_HANDLE; typedef unsigned long error_status_t; -#endif /* FREERDP_WINDOWS_TYPES_H */ +#endif /* WINPR_WTYPES_H */ diff --git a/libfreerdp-core/extension.h b/libfreerdp-core/extension.h index 27aafdfcc..25273023f 100644 --- a/libfreerdp-core/extension.h +++ b/libfreerdp-core/extension.h @@ -21,10 +21,11 @@ #ifndef __EXTENSION_H #define __EXTENSION_H +#include + #include #include #include -#include #define FREERDP_EXT_MAX_COUNT 16 diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index 760b4db4e..a8d0c98b0 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -756,7 +756,7 @@ int rpc_read(rdpRpc* rpc, uint8* data, int length) if (rpc->read_buffer_len > 0) { - if (rpc->read_buffer_len > length) + if (rpc->read_buffer_len > (uint32) length) { printf("rpc_read error: receiving buffer is not large enough\n"); return -1; diff --git a/libfreerdp-core/tcp.h b/libfreerdp-core/tcp.h index 1db16959a..45c32a83c 100644 --- a/libfreerdp-core/tcp.h +++ b/libfreerdp-core/tcp.h @@ -21,7 +21,7 @@ #ifndef __TCP_H #define __TCP_H -#include +#include #include #include diff --git a/libfreerdp-core/tsg.h b/libfreerdp-core/tsg.h index 9c270ae7a..ad0adc1ba 100644 --- a/libfreerdp-core/tsg.h +++ b/libfreerdp-core/tsg.h @@ -27,10 +27,10 @@ typedef struct rdp_tsg rdpTsg; #include "transport.h" #include +#include #include #include -#include #include #include #include diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c index c8f25e536..7b39fa13b 100644 --- a/libfreerdp-rail/window.c +++ b/libfreerdp-rail/window.c @@ -17,11 +17,11 @@ * limitations under the License. */ +#include #include #include #include #include -#include #include "librail.h" diff --git a/libfreerdp-utils/file.c b/libfreerdp-utils/file.c index 5a597f14c..f1985da0e 100644 --- a/libfreerdp-utils/file.c +++ b/libfreerdp-utils/file.c @@ -34,8 +34,8 @@ #define getcwd _getcwd #endif +#include #include -#include #ifndef _WIN32 #define PATH_SEPARATOR_STR "/" diff --git a/libfreerdp-utils/load_plugin.c b/libfreerdp-utils/load_plugin.c index b9bae3b03..6e64c45b3 100644 --- a/libfreerdp-utils/load_plugin.c +++ b/libfreerdp-utils/load_plugin.c @@ -22,11 +22,11 @@ #include #include #include +#include #include #include #include #include -#include #ifdef _WIN32 diff --git a/libfreerdp-utils/mutex.c b/libfreerdp-utils/mutex.c index 16003579d..a5e07ca8e 100644 --- a/libfreerdp-utils/mutex.c +++ b/libfreerdp-utils/mutex.c @@ -17,9 +17,9 @@ * limitations under the License. */ +#include #include #include -#include #ifdef _WIN32 #define freerdp_mutex_t HANDLE diff --git a/libfreerdp-utils/semaphore.c b/libfreerdp-utils/semaphore.c index 7e08a75d7..9cd87c422 100644 --- a/libfreerdp-utils/semaphore.c +++ b/libfreerdp-utils/semaphore.c @@ -17,9 +17,9 @@ * limitations under the License. */ +#include #include #include -#include #if defined __APPLE__ diff --git a/libfreerdp-utils/sleep.c b/libfreerdp-utils/sleep.c index 9752e0d2a..830cad615 100644 --- a/libfreerdp-utils/sleep.c +++ b/libfreerdp-utils/sleep.c @@ -17,8 +17,8 @@ * limitations under the License. */ +#include #include -#include #include diff --git a/libfreerdp-utils/tcp.c b/libfreerdp-utils/tcp.c index 695855d15..81ece04d7 100644 --- a/libfreerdp-utils/tcp.c +++ b/libfreerdp-utils/tcp.c @@ -45,7 +45,7 @@ #else /* ifdef _WIN32 */ -#include +#include #define SHUT_RDWR SD_BOTH #define close(_fd) closesocket(_fd) #endif diff --git a/libfreerdp-utils/thread.c b/libfreerdp-utils/thread.c index 2251cdd0d..d25125917 100644 --- a/libfreerdp-utils/thread.c +++ b/libfreerdp-utils/thread.c @@ -22,7 +22,7 @@ #include #include -#include +#include #ifdef _WIN32 #ifdef _MSC_VER diff --git a/libfreerdp-utils/time.c b/libfreerdp-utils/time.c index 2e50796d2..fbcf46971 100644 --- a/libfreerdp-utils/time.c +++ b/libfreerdp-utils/time.c @@ -17,8 +17,8 @@ * limitations under the License. */ +#include #include -#include uint64 freerdp_windows_gmtime() { diff --git a/libfreerdp-utils/unicode.c b/libfreerdp-utils/unicode.c index 960d2360d..e06ccec2a 100644 --- a/libfreerdp-utils/unicode.c +++ b/libfreerdp-utils/unicode.c @@ -114,7 +114,7 @@ char* freerdp_uniconv_out(UNICONV* uniconv, const char *str, size_t* pout_len) ibl = strlen(str); obl = 2 * ibl; - pin = str; + pin = (char*) str; pout0 = xmalloc(obl + 2); pout = pout0; diff --git a/libfreerdp-utils/wait_obj.c b/libfreerdp-utils/wait_obj.c index 65f6fb880..a9f2e8ef2 100644 --- a/libfreerdp-utils/wait_obj.c +++ b/libfreerdp-utils/wait_obj.c @@ -18,12 +18,13 @@ */ #include "config.h" + #include #include #include +#include #include #include -#include #ifndef _WIN32 #include diff --git a/libwinpr-rpc/ndr.c b/libwinpr-rpc/ndr.c index b3c8f85b4..6c29b7ef8 100644 --- a/libwinpr-rpc/ndr.c +++ b/libwinpr-rpc/ndr.c @@ -17,6 +17,8 @@ * limitations under the License. */ +#include + #include /** From 31f2fd3a8ad0548ea338a8bf9fd5d3b61860a810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 4 May 2012 19:48:53 -0400 Subject: [PATCH 44/47] libwinpr-sspi: rename from libfreerdp-sspi --- CMakeLists.txt | 2 +- include/{freerdp/sspi => winpr}/credssp.h | 2 +- include/{freerdp/sspi => winpr}/sspi.h | 0 libfreerdp-core/CMakeLists.txt | 2 +- libfreerdp-core/rpc.h | 2 +- libfreerdp-core/transport.c | 2 +- libfreerdp-core/transport.h | 3 +- .../CMakeLists.txt | 34 +++++++++---------- .../Kerberos/kerberos.c | 2 +- .../Kerberos/kerberos.h | 2 +- .../Kerberos/kerberos_crypto.c | 0 .../Kerberos/kerberos_crypto.h | 0 .../Kerberos/kerberos_decode.c | 0 .../Kerberos/kerberos_decode.h | 0 .../Kerberos/kerberos_encode.c | 0 .../Kerberos/kerberos_encode.h | 0 .../NTLM/ntlm.c | 2 +- .../NTLM/ntlm.h | 2 +- .../NTLM/ntlm_av_pairs.c | 0 .../NTLM/ntlm_av_pairs.h | 0 .../NTLM/ntlm_compute.c | 0 .../NTLM/ntlm_compute.h | 0 .../NTLM/ntlm_message.c | 0 .../NTLM/ntlm_message.h | 0 .../Negotiate/negotiate.c | 2 +- .../Negotiate/negotiate.h | 2 +- {libfreerdp-sspi => libwinpr-sspi}/credssp.c | 4 +-- {libfreerdp-sspi => libwinpr-sspi}/sspi.c | 2 +- {libfreerdp-sspi => libwinpr-sspi}/sspi.h | 3 +- 29 files changed, 35 insertions(+), 33 deletions(-) rename include/{freerdp/sspi => winpr}/credssp.h (98%) rename include/{freerdp/sspi => winpr}/sspi.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/CMakeLists.txt (64%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos.c (99%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos.h (99%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_crypto.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_crypto.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_decode.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_decode.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_encode.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Kerberos/kerberos_encode.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm.c (99%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm.h (98%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_av_pairs.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_av_pairs.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_compute.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_compute.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_message.c (100%) rename {libfreerdp-sspi => libwinpr-sspi}/NTLM/ntlm_message.h (100%) rename {libfreerdp-sspi => libwinpr-sspi}/Negotiate/negotiate.c (99%) rename {libfreerdp-sspi => libwinpr-sspi}/Negotiate/negotiate.h (97%) rename {libfreerdp-sspi => libwinpr-sspi}/credssp.c (99%) rename {libfreerdp-sspi => libwinpr-sspi}/sspi.c (99%) rename {libfreerdp-sspi => libwinpr-sspi}/sspi.h (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 314bf6964..aae3e6268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,12 +156,12 @@ add_subdirectory(libfreerdp-rail) add_subdirectory(libfreerdp-cache) add_subdirectory(libfreerdp-codec) add_subdirectory(libfreerdp-crypto) -add_subdirectory(libfreerdp-sspi) add_subdirectory(libfreerdp-channels) add_subdirectory(libfreerdp-locale) add_subdirectory(libfreerdp-core) add_subdirectory(libwinpr-rpc) +add_subdirectory(libwinpr-sspi) if(NOT WIN32) add_subdirectory(channels) diff --git a/include/freerdp/sspi/credssp.h b/include/winpr/credssp.h similarity index 98% rename from include/freerdp/sspi/credssp.h rename to include/winpr/credssp.h index ffc470ed9..2e690ccd0 100644 --- a/include/freerdp/sspi/credssp.h +++ b/include/winpr/credssp.h @@ -28,7 +28,7 @@ typedef struct rdp_credssp rdpCredssp; #include #include -#include +#include #include #include diff --git a/include/freerdp/sspi/sspi.h b/include/winpr/sspi.h similarity index 100% rename from include/freerdp/sspi/sspi.h rename to include/winpr/sspi.h diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 6aa6da49e..4161e101e 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -105,11 +105,11 @@ endif() target_link_libraries(freerdp-core freerdp-utils) target_link_libraries(freerdp-core freerdp-codec) target_link_libraries(freerdp-core freerdp-crypto) -target_link_libraries(freerdp-core freerdp-sspi) target_link_libraries(freerdp-core freerdp-locale) target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES}) target_link_libraries(freerdp-core winpr-rpc) +target_link_libraries(freerdp-core winpr-sspi) install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-core/rpc.h b/libfreerdp-core/rpc.h index 40acbca4e..ff9f2db82 100644 --- a/libfreerdp-core/rpc.h +++ b/libfreerdp-core/rpc.h @@ -30,9 +30,9 @@ typedef struct rdp_ntlm_http rdpNtlmHttp; #include "transport.h" #include +#include #include #include -#include #include #include #include diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index 629d542e2..46c21652d 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -39,7 +39,7 @@ #include "fastpath.h" #include "transport.h" -#include +#include #define BUFFER_SIZE 16384 diff --git a/libfreerdp-core/transport.h b/libfreerdp-core/transport.h index b0075d6e0..e774cadce 100644 --- a/libfreerdp-core/transport.h +++ b/libfreerdp-core/transport.h @@ -32,8 +32,9 @@ typedef struct rdp_transport rdpTransport; #include "tcp.h" #include "tsg.h" + +#include #include -#include #include #include diff --git a/libfreerdp-sspi/CMakeLists.txt b/libwinpr-sspi/CMakeLists.txt similarity index 64% rename from libfreerdp-sspi/CMakeLists.txt rename to libwinpr-sspi/CMakeLists.txt index d90f430a2..08f8c39c2 100644 --- a/libfreerdp-sspi/CMakeLists.txt +++ b/libwinpr-sspi/CMakeLists.txt @@ -1,5 +1,5 @@ -# FreeRDP: A Remote Desktop Protocol Client -# libfreerdp-sspi cmake build script +# WinPR: Windows Portable Runtime +# libwinpr-sspi cmake build script # # Copyright 2011 O.S. Systems Software Ltda. # Copyright 2011 Otavio Salvador @@ -17,7 +17,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(FREERDP_SSPI_NTLM_SRCS +set(WINPR_SSPI_NTLM_SRCS NTLM/ntlm_av_pairs.c NTLM/ntlm_av_pairs.h NTLM/ntlm_compute.c @@ -27,7 +27,7 @@ set(FREERDP_SSPI_NTLM_SRCS NTLM/ntlm.c NTLM/ntlm.h) -set(FREERDP_SSPI_KERBEROS_SRCS +set(WINPR_SSPI_KERBEROS_SRCS Kerberos/kerberos_crypto.c Kerberos/kerberos_crypto.h Kerberos/kerberos_decode.c @@ -37,36 +37,36 @@ set(FREERDP_SSPI_KERBEROS_SRCS Kerberos/kerberos.c Kerberos/kerberos.h) -set(FREERDP_SSPI_NEGOTIATE_SRCS +set(WINPR_SSPI_NEGOTIATE_SRCS Negotiate/negotiate.c Negotiate/negotiate.h) -set(FREERDP_SSPI_SRCS +set(WINPR_SSPI_SRCS sspi.c sspi.h credssp.c) if(NOT WITH_NATIVE_SSPI) - set(FREERDP_SSPI_SRCS - ${FREERDP_SSPI_NTLM_SRCS} - ${FREERDP_SSPI_KERBEROS_SRCS} - ${FREERDP_SSPI_NEGOTIATE_SRCS} - ${FREERDP_SSPI_SRCS}) + set(WINPR_SSPI_SRCS + ${WINPR_SSPI_NTLM_SRCS} + ${WINPR_SSPI_KERBEROS_SRCS} + ${WINPR_SSPI_NEGOTIATE_SRCS} + ${WINPR_SSPI_SRCS}) else() add_definitions(-DNATIVE_SSPI) endif() -add_library(freerdp-sspi ${FREERDP_SSPI_SRCS}) +add_library(winpr-sspi ${WINPR_SSPI_SRCS}) include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) -set_target_properties(freerdp-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") +set_target_properties(winpr-sspi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") -target_link_libraries(freerdp-sspi freerdp-utils) -target_link_libraries(freerdp-sspi freerdp-crypto) -target_link_libraries(freerdp-sspi ${ZLIB_LIBRARIES}) +target_link_libraries(winpr-sspi freerdp-utils) +target_link_libraries(winpr-sspi freerdp-crypto) +target_link_libraries(winpr-sspi ${ZLIB_LIBRARIES}) -install(TARGETS freerdp-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS winpr-sspi DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-sspi/Kerberos/kerberos.c b/libwinpr-sspi/Kerberos/kerberos.c similarity index 99% rename from libfreerdp-sspi/Kerberos/kerberos.c rename to libwinpr-sspi/Kerberos/kerberos.c index aa304b901..ef21bd3bf 100644 --- a/libfreerdp-sspi/Kerberos/kerberos.c +++ b/libwinpr-sspi/Kerberos/kerberos.c @@ -37,7 +37,7 @@ #include "kerberos_encode.h" #include "kerberos_decode.h" -#include +#include #include #include diff --git a/libfreerdp-sspi/Kerberos/kerberos.h b/libwinpr-sspi/Kerberos/kerberos.h similarity index 99% rename from libfreerdp-sspi/Kerberos/kerberos.h rename to libwinpr-sspi/Kerberos/kerberos.h index 6d65c244f..0f881bcc6 100644 --- a/libfreerdp-sspi/Kerberos/kerberos.h +++ b/libwinpr-sspi/Kerberos/kerberos.h @@ -34,11 +34,11 @@ #include +#include #include #include #include #include -#include #define MSKRB_OID "1.2.840.48018.1.2.2" #define STDKRB_OID "1.2.840.113554.1.2.2" diff --git a/libfreerdp-sspi/Kerberos/kerberos_crypto.c b/libwinpr-sspi/Kerberos/kerberos_crypto.c similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_crypto.c rename to libwinpr-sspi/Kerberos/kerberos_crypto.c diff --git a/libfreerdp-sspi/Kerberos/kerberos_crypto.h b/libwinpr-sspi/Kerberos/kerberos_crypto.h similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_crypto.h rename to libwinpr-sspi/Kerberos/kerberos_crypto.h diff --git a/libfreerdp-sspi/Kerberos/kerberos_decode.c b/libwinpr-sspi/Kerberos/kerberos_decode.c similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_decode.c rename to libwinpr-sspi/Kerberos/kerberos_decode.c diff --git a/libfreerdp-sspi/Kerberos/kerberos_decode.h b/libwinpr-sspi/Kerberos/kerberos_decode.h similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_decode.h rename to libwinpr-sspi/Kerberos/kerberos_decode.h diff --git a/libfreerdp-sspi/Kerberos/kerberos_encode.c b/libwinpr-sspi/Kerberos/kerberos_encode.c similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_encode.c rename to libwinpr-sspi/Kerberos/kerberos_encode.c diff --git a/libfreerdp-sspi/Kerberos/kerberos_encode.h b/libwinpr-sspi/Kerberos/kerberos_encode.h similarity index 100% rename from libfreerdp-sspi/Kerberos/kerberos_encode.h rename to libwinpr-sspi/Kerberos/kerberos_encode.h diff --git a/libfreerdp-sspi/NTLM/ntlm.c b/libwinpr-sspi/NTLM/ntlm.c similarity index 99% rename from libfreerdp-sspi/NTLM/ntlm.c rename to libwinpr-sspi/NTLM/ntlm.c index b2b99586c..f2a9cb82f 100644 --- a/libfreerdp-sspi/NTLM/ntlm.c +++ b/libwinpr-sspi/NTLM/ntlm.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "ntlm.h" #include "../sspi.h" diff --git a/libfreerdp-sspi/NTLM/ntlm.h b/libwinpr-sspi/NTLM/ntlm.h similarity index 98% rename from libfreerdp-sspi/NTLM/ntlm.h rename to libwinpr-sspi/NTLM/ntlm.h index 08e724373..333a577b4 100644 --- a/libfreerdp-sspi/NTLM/ntlm.h +++ b/libwinpr-sspi/NTLM/ntlm.h @@ -20,7 +20,7 @@ #ifndef FREERDP_SSPI_NTLM_PRIVATE_H #define FREERDP_SSPI_NTLM_PRIVATE_H -#include +#include #include #include diff --git a/libfreerdp-sspi/NTLM/ntlm_av_pairs.c b/libwinpr-sspi/NTLM/ntlm_av_pairs.c similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_av_pairs.c rename to libwinpr-sspi/NTLM/ntlm_av_pairs.c diff --git a/libfreerdp-sspi/NTLM/ntlm_av_pairs.h b/libwinpr-sspi/NTLM/ntlm_av_pairs.h similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_av_pairs.h rename to libwinpr-sspi/NTLM/ntlm_av_pairs.h diff --git a/libfreerdp-sspi/NTLM/ntlm_compute.c b/libwinpr-sspi/NTLM/ntlm_compute.c similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_compute.c rename to libwinpr-sspi/NTLM/ntlm_compute.c diff --git a/libfreerdp-sspi/NTLM/ntlm_compute.h b/libwinpr-sspi/NTLM/ntlm_compute.h similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_compute.h rename to libwinpr-sspi/NTLM/ntlm_compute.h diff --git a/libfreerdp-sspi/NTLM/ntlm_message.c b/libwinpr-sspi/NTLM/ntlm_message.c similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_message.c rename to libwinpr-sspi/NTLM/ntlm_message.c diff --git a/libfreerdp-sspi/NTLM/ntlm_message.h b/libwinpr-sspi/NTLM/ntlm_message.h similarity index 100% rename from libfreerdp-sspi/NTLM/ntlm_message.h rename to libwinpr-sspi/NTLM/ntlm_message.h diff --git a/libfreerdp-sspi/Negotiate/negotiate.c b/libwinpr-sspi/Negotiate/negotiate.c similarity index 99% rename from libfreerdp-sspi/Negotiate/negotiate.c rename to libwinpr-sspi/Negotiate/negotiate.c index a37357e3a..a5e3c534a 100644 --- a/libfreerdp-sspi/Negotiate/negotiate.c +++ b/libwinpr-sspi/Negotiate/negotiate.c @@ -17,7 +17,7 @@ * limitations under the License. */ -#include +#include #include #include "negotiate.h" diff --git a/libfreerdp-sspi/Negotiate/negotiate.h b/libwinpr-sspi/Negotiate/negotiate.h similarity index 97% rename from libfreerdp-sspi/Negotiate/negotiate.h rename to libwinpr-sspi/Negotiate/negotiate.h index 5ce064a75..ab0e82bbb 100644 --- a/libfreerdp-sspi/Negotiate/negotiate.h +++ b/libwinpr-sspi/Negotiate/negotiate.h @@ -20,7 +20,7 @@ #ifndef FREERDP_SSPI_NEGOTIATE_PRIVATE_H #define FREERDP_SSPI_NEGOTIATE_PRIVATE_H -#include +#include #include #include "../Kerberos/kerberos.h" diff --git a/libfreerdp-sspi/credssp.c b/libwinpr-sspi/credssp.c similarity index 99% rename from libfreerdp-sspi/credssp.c rename to libwinpr-sspi/credssp.c index 8cf8b480a..151710e6b 100644 --- a/libfreerdp-sspi/credssp.c +++ b/libwinpr-sspi/credssp.c @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include "sspi.h" diff --git a/libfreerdp-sspi/sspi.c b/libwinpr-sspi/sspi.c similarity index 99% rename from libfreerdp-sspi/sspi.c rename to libwinpr-sspi/sspi.c index a637f1e87..6b7ce5ee0 100644 --- a/libfreerdp-sspi/sspi.c +++ b/libwinpr-sspi/sspi.c @@ -19,7 +19,7 @@ #include -#include +#include #include "sspi.h" diff --git a/libfreerdp-sspi/sspi.h b/libwinpr-sspi/sspi.h similarity index 98% rename from libfreerdp-sspi/sspi.h rename to libwinpr-sspi/sspi.h index e8c01a638..0de4ea092 100644 --- a/libfreerdp-sspi/sspi.h +++ b/libwinpr-sspi/sspi.h @@ -21,8 +21,9 @@ #define FREERDP_AUTH_SSPI_PRIVATE_H #include "config.h" + +#include #include -#include struct _CREDENTIALS { From bbae05685cbaef7e9506da904267008b465392eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 4 May 2012 21:50:32 -0400 Subject: [PATCH 45/47] libwinpr-rpc: split NDR implementation into multiple files --- include/winpr/ndr.h | 5 + libwinpr-rpc/CMakeLists.txt | 9 + libwinpr-rpc/ndr.c | 1658 +------------------------------- libwinpr-rpc/ndr_array.c | 137 +++ libwinpr-rpc/ndr_array.h | 31 + libwinpr-rpc/ndr_context.c | 66 ++ libwinpr-rpc/ndr_context.h | 27 + libwinpr-rpc/ndr_correlation.c | 187 ++++ libwinpr-rpc/ndr_correlation.h | 29 + libwinpr-rpc/ndr_pointer.c | 322 +++++++ libwinpr-rpc/ndr_pointer.h | 30 + libwinpr-rpc/ndr_private.c | 552 +++++++++++ libwinpr-rpc/ndr_private.h | 42 + libwinpr-rpc/ndr_simple.c | 193 ++++ libwinpr-rpc/ndr_simple.h | 35 + libwinpr-rpc/ndr_string.c | 35 + libwinpr-rpc/ndr_string.h | 28 + libwinpr-rpc/ndr_structure.c | 313 ++++++ libwinpr-rpc/ndr_structure.h | 30 + libwinpr-rpc/ndr_union.c | 35 + libwinpr-rpc/ndr_union.h | 28 + 21 files changed, 2144 insertions(+), 1648 deletions(-) create mode 100644 libwinpr-rpc/ndr_array.c create mode 100644 libwinpr-rpc/ndr_array.h create mode 100644 libwinpr-rpc/ndr_context.c create mode 100644 libwinpr-rpc/ndr_context.h create mode 100644 libwinpr-rpc/ndr_correlation.c create mode 100644 libwinpr-rpc/ndr_correlation.h create mode 100644 libwinpr-rpc/ndr_pointer.c create mode 100644 libwinpr-rpc/ndr_pointer.h create mode 100644 libwinpr-rpc/ndr_private.c create mode 100644 libwinpr-rpc/ndr_private.h create mode 100644 libwinpr-rpc/ndr_simple.c create mode 100644 libwinpr-rpc/ndr_simple.h create mode 100644 libwinpr-rpc/ndr_string.c create mode 100644 libwinpr-rpc/ndr_string.h create mode 100644 libwinpr-rpc/ndr_structure.c create mode 100644 libwinpr-rpc/ndr_structure.h create mode 100644 libwinpr-rpc/ndr_union.c create mode 100644 libwinpr-rpc/ndr_union.h diff --git a/include/winpr/ndr.h b/include/winpr/ndr.h index ed288e3a2..e6a8ab79e 100644 --- a/include/winpr/ndr.h +++ b/include/winpr/ndr.h @@ -520,6 +520,11 @@ typedef enum _NDR_PHASE #define NdrFcLong(s) (byte)(s & 0xFF), (byte)((s & 0x0000FF00) >> 8), \ (byte)((s & 0x00FF0000) >> 16), (byte)(s >> 24) +typedef void (*NDR_TYPE_SIZE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + WINPR_API CLIENT_CALL_RETURN RPC_VAR_ENTRY NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); #endif /* WINPR_RPC_NDR_H */ diff --git a/libwinpr-rpc/CMakeLists.txt b/libwinpr-rpc/CMakeLists.txt index 5d7a9b343..af607cbae 100644 --- a/libwinpr-rpc/CMakeLists.txt +++ b/libwinpr-rpc/CMakeLists.txt @@ -20,6 +20,15 @@ set(WINPR_RPC_SRCS rpc.c ndr.c + ndr_array.c ndr_array.h + ndr_context.c ndr_context.h + ndr_correlation.c ndr_correlation.h + ndr_pointer.c ndr_pointer.h + ndr_private.c ndr_private.h + ndr_simple.c ndr_simple.h + ndr_string.c ndr_string.h + ndr_structure.c ndr_structure.h + ndr_union.c ndr_union.h midl.c) add_library(winpr-rpc ${WINPR_RPC_SRCS}) diff --git a/libwinpr-rpc/ndr.c b/libwinpr-rpc/ndr.c index 6c29b7ef8..ccba296e3 100644 --- a/libwinpr-rpc/ndr.c +++ b/libwinpr-rpc/ndr.c @@ -21,1659 +21,21 @@ #include +#include "ndr_array.h" +#include "ndr_context.h" +#include "ndr_pointer.h" +#include "ndr_simple.h" +#include "ndr_string.h" +#include "ndr_structure.h" +#include "ndr_union.h" + +#include "ndr_private.h" + /** * MSRPC NDR Types Technical Overview: * http://dvlabs.tippingpoint.com/blog/2007/11/24/msrpc-ndr-types/ */ -const char* FC_TYPE_STRINGS[] = -{ - "FC_ZERO", - "FC_BYTE", - "FC_CHAR", - "FC_SMALL", - "FC_USMALL", - "FC_WCHAR", - "FC_SHORT", - "FC_USHORT", - "FC_LONG", - "FC_ULONG", - "FC_FLOAT", - "FC_HYPER", - "FC_DOUBLE", - "FC_ENUM16", - "FC_ENUM32", - "FC_IGNORE", - "FC_ERROR_STATUS_T", - "FC_RP", - "FC_UP", - "FC_OP", - "FC_FP", - "FC_STRUCT", - "FC_PSTRUCT", - "FC_CSTRUCT", - "FC_CPSTRUCT", - "FC_CVSTRUCT", - "FC_BOGUS_STRUCT", - "FC_CARRAY", - "FC_CVARRAY", - "FC_SMFARRAY", - "FC_LGFARRAY", - "FC_SMVARRAY", - "FC_LGVARRAY", - "FC_BOGUS_ARRAY", - "FC_C_CSTRING", - "FC_C_BSTRING", - "FC_C_SSTRING", - "FC_C_WSTRING", - "FC_CSTRING", - "FC_BSTRING", - "FC_SSTRING", - "FC_WSTRING", - "FC_ENCAPSULATED_UNION", - "FC_NON_ENCAPSULATED_UNION", - "FC_BYTE_COUNT_POINTER", - "FC_TRANSMIT_AS", - "FC_REPRESENT_AS", - "FC_IP", - "FC_BIND_CONTEXT", - "FC_BIND_GENERIC", - "FC_BIND_PRIMITIVE", - "FC_AUTO_HANDLE", - "FC_CALLBACK_HANDLE", - "FC_UNUSED1", - "FC_POINTER", - "FC_ALIGNM2", - "FC_ALIGNM4", - "FC_ALIGNM8", - "FC_UNUSED2", - "FC_UNUSED3", - "FC_UNUSED4", - "FC_STRUCTPAD1", - "FC_STRUCTPAD2", - "FC_STRUCTPAD3", - "FC_STRUCTPAD4", - "FC_STRUCTPAD5", - "FC_STRUCTPAD6", - "FC_STRUCTPAD7", - "FC_STRING_SIZED", - "FC_UNUSED5", - "FC_NO_REPEAT", - "FC_FIXED_REPEAT", - "FC_VARIABLE_REPEAT", - "FC_FIXED_OFFSET", - "FC_VARIABLE_OFFSET", - "FC_PP", - "FC_EMBEDDED_COMPLEX", - "FC_IN_PARAM", - "FC_IN_PARAM_BASETYPE", - "FC_IN_PARAM_NO_FREE_INST", - "FC_IN_OUT_PARAM", - "FC_OUT_PARAM", - "FC_RETURN_PARAM", - "FC_RETURN_PARAM_BASETYPE", - "FC_DEREFERENCE", - "FC_DIV_2", - "FC_MULT_2", - "FC_ADD_1", - "FC_SUB_1", - "FC_CALLBACK", - "FC_CONSTANT_IID", - "FC_END", - "FC_PAD", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "", "", "", "", "", "", - "FC_SPLIT_DEREFERENCE", - "FC_SPLIT_DIV_2", - "FC_SPLIT_MULT_2", - "FC_SPLIT_ADD_1", - "FC_SPLIT_SUB_1", - "FC_SPLIT_CALLBACK", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "FC_HARD_STRUCT", - "FC_TRANSMIT_AS_PTR", - "FC_REPRESENT_AS_PTR", - "FC_USER_MARSHAL", - "FC_PIPE", - "FC_BLKHOLE", - "FC_RANGE", - "FC_INT3264", - "FC_UINT3264", - "FC_END_OF_UNIVERSE", -}; - -typedef void (*NDR_TYPE_SIZE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); -typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); -typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); -typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); -void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); -void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); -void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); - -const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] = -{ - NULL, /* FC_ZERO */ - NdrSimpleTypeBufferSize, /* FC_BYTE */ - NdrSimpleTypeBufferSize, /* FC_CHAR */ - NdrSimpleTypeBufferSize, /* FC_SMALL */ - NdrSimpleTypeBufferSize, /* FC_USMALL */ - NdrSimpleTypeBufferSize, /* FC_WCHAR */ - NdrSimpleTypeBufferSize, /* FC_SHORT */ - NdrSimpleTypeBufferSize, /* FC_USHORT */ - NdrSimpleTypeBufferSize, /* FC_LONG */ - NdrSimpleTypeBufferSize, /* FC_ULONG */ - NdrSimpleTypeBufferSize, /* FC_FLOAT */ - NdrSimpleTypeBufferSize, /* FC_HYPER */ - NdrSimpleTypeBufferSize, /* FC_DOUBLE */ - NdrSimpleTypeBufferSize, /* FC_ENUM16 */ - NdrSimpleTypeBufferSize, /* FC_ENUM32 */ - NdrSimpleTypeBufferSize, /* FC_IGNORE */ - NdrSimpleTypeBufferSize, /* FC_ERROR_STATUS_T */ - NdrPointerBufferSize, /* FC_RP */ - NdrPointerBufferSize, /* FC_UP */ - NdrPointerBufferSize, /* FC_OP */ - NdrPointerBufferSize, /* FC_FP */ - NdrSimpleStructBufferSize, /* FC_STRUCT */ - NdrSimpleStructBufferSize, /* FC_PSTRUCT */ - NdrConformantStructBufferSize, /* FC_CSTRUCT */ - NdrConformantStructBufferSize, /* FC_CPSTRUCT */ - NdrConformantVaryingStructBufferSize, /* FC_CVSTRUCT */ - NdrComplexStructBufferSize, /* FC_BOGUS_STRUCT */ - NdrConformantArrayBufferSize, /* FC_CARRAY */ - NdrConformantVaryingArrayBufferSize, /* FC_CVARRAY */ - NdrFixedArrayBufferSize, /* FC_SMFARRAY */ - NdrFixedArrayBufferSize, /* FC_LGFARRAY */ - NdrVaryingArrayBufferSize, /* FC_SMVARRAY */ - NdrVaryingArrayBufferSize, /* FC_LGVARRAY */ - NdrComplexArrayBufferSize, /* FC_BOGUS_ARRAY */ - NdrConformantStringBufferSize, /* FC_C_CSTRING */ - NULL, /* FC_C_BSTRING */ - NULL, /* FC_C_SSTRING */ - NdrConformantStringBufferSize, /* FC_C_WSTRING */ - NdrNonConformantStringBufferSize, /* FC_CSTRING */ - NULL, /* FC_BSTRING */ - NULL, /* FC_SSTRING */ - NULL, /* FC_WSTRING */ - NdrEncapsulatedUnionBufferSize, /* FC_ENCAPSULATED_UNION */ - NdrNonEncapsulatedUnionBufferSize, /* FC_NON_ENCAPSULATED_UNION */ - NdrByteCountPointerBufferSize, /* FC_BYTE_COUNT_POINTER */ - NULL, /* FC_TRANSMIT_AS */ - NULL, /* FC_REPRESENT_AS */ - NULL, /* FC_IP */ - NdrContextHandleBufferSize, /* FC_BIND_CONTEXT */ - NULL, /* FC_BIND_GENERIC */ - NULL, /* FC_BIND_PRIMITIVE */ - NULL, /* FC_AUTO_HANDLE */ - NULL, /* FC_CALLBACK_HANDLE */ - NULL, /* FC_UNUSED1 */ - NULL, /* FC_POINTER */ - NULL, /* FC_ALIGNM2 */ - NULL, /* FC_ALIGNM4 */ - NULL, /* FC_ALIGNM8 */ - NULL, /* FC_UNUSED2 */ - NULL, /* FC_UNUSED3 */ - NULL, /* FC_UNUSED4 */ - NULL, /* FC_STRUCTPAD1 */ - NULL, /* FC_STRUCTPAD2 */ - NULL, /* FC_STRUCTPAD3 */ - NULL, /* FC_STRUCTPAD4 */ - NULL, /* FC_STRUCTPAD5 */ - NULL, /* FC_STRUCTPAD6 */ - NULL, /* FC_STRUCTPAD7 */ - NULL, /* FC_STRING_SIZED */ - NULL, /* FC_UNUSED5 */ - NULL, /* FC_NO_REPEAT */ - NULL, /* FC_FIXED_REPEAT */ - NULL, /* FC_VARIABLE_REPEAT */ - NULL, /* FC_FIXED_OFFSET */ - NULL, /* FC_VARIABLE_OFFSET */ - NULL, /* FC_PP */ - NULL, /* FC_EMBEDDED_COMPLEX */ - NULL, /* FC_IN_PARAM */ - NULL, /* FC_IN_PARAM_BASETYPE */ - NULL, /* FC_IN_PARAM_NO_FREE_INST */ - NULL, /* FC_IN_OUT_PARAM */ - NULL, /* FC_OUT_PARAM */ - NULL, /* FC_RETURN_PARAM */ - NULL, /* FC_RETURN_PARAM_BASETYPE */ - NULL, /* FC_DEREFERENCE */ - NULL, /* FC_DIV_2 */ - NULL, /* FC_MULT_2 */ - NULL, /* FC_ADD_1 */ - NULL, /* FC_SUB_1 */ - NULL, /* FC_CALLBACK */ - NULL, /* FC_CONSTANT_IID */ - NULL, /* FC_END */ - NULL, /* FC_PAD */ -}; - -const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[] = -{ - NULL, /* FC_ZERO */ - NdrSimpleTypeMarshall, /* FC_BYTE */ - NdrSimpleTypeMarshall, /* FC_CHAR */ - NdrSimpleTypeMarshall, /* FC_SMALL */ - NdrSimpleTypeMarshall, /* FC_USMALL */ - NdrSimpleTypeMarshall, /* FC_WCHAR */ - NdrSimpleTypeMarshall, /* FC_SHORT */ - NdrSimpleTypeMarshall, /* FC_USHORT */ - NdrSimpleTypeMarshall, /* FC_LONG */ - NdrSimpleTypeMarshall, /* FC_ULONG */ - NdrSimpleTypeMarshall, /* FC_FLOAT */ - NdrSimpleTypeMarshall, /* FC_HYPER */ - NdrSimpleTypeMarshall, /* FC_DOUBLE */ - NdrSimpleTypeMarshall, /* FC_ENUM16 */ - NdrSimpleTypeMarshall, /* FC_ENUM32 */ - NdrSimpleTypeMarshall, /* FC_IGNORE */ - NULL, /* FC_ERROR_STATUS_T */ - NULL, /* FC_RP */ - NULL, /* FC_UP */ - NULL, /* FC_OP */ - NULL, /* FC_FP */ - NULL, /* FC_STRUCT */ - NULL, /* FC_PSTRUCT */ - NULL, /* FC_CSTRUCT */ - NULL, /* FC_CPSTRUCT */ - NULL, /* FC_CVSTRUCT */ - NULL, /* FC_BOGUS_STRUCT */ - NULL, /* FC_CARRAY */ - NULL, /* FC_CVARRAY */ - NULL, /* FC_SMFARRAY */ - NULL, /* FC_LGFARRAY */ - NULL, /* FC_SMVARRAY */ - NULL, /* FC_LGVARRAY */ - NULL, /* FC_BOGUS_ARRAY */ - NULL, /* FC_C_CSTRING */ - NULL, /* FC_C_BSTRING */ - NULL, /* FC_C_SSTRING */ - NULL, /* FC_C_WSTRING */ - NULL, /* FC_CSTRING */ - NULL, /* FC_BSTRING */ - NULL, /* FC_SSTRING */ - NULL, /* FC_WSTRING */ - NULL, /* FC_ENCAPSULATED_UNION */ - NULL, /* FC_NON_ENCAPSULATED_UNION */ - NULL, /* FC_BYTE_COUNT_POINTER */ - NULL, /* FC_TRANSMIT_AS */ - NULL, /* FC_REPRESENT_AS */ - NULL, /* FC_IP */ - NULL, /* FC_BIND_CONTEXT */ - NULL, /* FC_BIND_GENERIC */ - NULL, /* FC_BIND_PRIMITIVE */ - NULL, /* FC_AUTO_HANDLE */ - NULL, /* FC_CALLBACK_HANDLE */ - NULL, /* FC_UNUSED1 */ - NULL, /* FC_POINTER */ - NULL, /* FC_ALIGNM2 */ - NULL, /* FC_ALIGNM4 */ - NULL, /* FC_ALIGNM8 */ - NULL, /* FC_UNUSED2 */ - NULL, /* FC_UNUSED3 */ - NULL, /* FC_UNUSED4 */ - NULL, /* FC_STRUCTPAD1 */ - NULL, /* FC_STRUCTPAD2 */ - NULL, /* FC_STRUCTPAD3 */ - NULL, /* FC_STRUCTPAD4 */ - NULL, /* FC_STRUCTPAD5 */ - NULL, /* FC_STRUCTPAD6 */ - NULL, /* FC_STRUCTPAD7 */ - NULL, /* FC_STRING_SIZED */ - NULL, /* FC_UNUSED5 */ - NULL, /* FC_NO_REPEAT */ - NULL, /* FC_FIXED_REPEAT */ - NULL, /* FC_VARIABLE_REPEAT */ - NULL, /* FC_FIXED_OFFSET */ - NULL, /* FC_VARIABLE_OFFSET */ - NULL, /* FC_PP */ - NULL, /* FC_EMBEDDED_COMPLEX */ - NULL, /* FC_IN_PARAM */ - NULL, /* FC_IN_PARAM_BASETYPE */ - NULL, /* FC_IN_PARAM_NO_FREE_INST */ - NULL, /* FC_IN_OUT_PARAM */ - NULL, /* FC_OUT_PARAM */ - NULL, /* FC_RETURN_PARAM */ - NULL, /* FC_RETURN_PARAM_BASETYPE */ - NULL, /* FC_DEREFERENCE */ - NULL, /* FC_DIV_2 */ - NULL, /* FC_MULT_2 */ - NULL, /* FC_ADD_1 */ - NULL, /* FC_SUB_1 */ - NULL, /* FC_CALLBACK */ - NULL, /* FC_CONSTANT_IID */ - NULL, /* FC_END */ - NULL, /* FC_PAD */ -}; - -const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[] = -{ - NULL, /* FC_ZERO */ - NdrSimpleTypeUnmarshall, /* FC_BYTE */ - NdrSimpleTypeUnmarshall, /* FC_CHAR */ - NdrSimpleTypeUnmarshall, /* FC_SMALL */ - NdrSimpleTypeUnmarshall, /* FC_USMALL */ - NdrSimpleTypeUnmarshall, /* FC_WCHAR */ - NdrSimpleTypeUnmarshall, /* FC_SHORT */ - NdrSimpleTypeUnmarshall, /* FC_USHORT */ - NdrSimpleTypeUnmarshall, /* FC_LONG */ - NdrSimpleTypeUnmarshall, /* FC_ULONG */ - NdrSimpleTypeUnmarshall, /* FC_FLOAT */ - NdrSimpleTypeUnmarshall, /* FC_HYPER */ - NdrSimpleTypeUnmarshall, /* FC_DOUBLE */ - NdrSimpleTypeUnmarshall, /* FC_ENUM16 */ - NdrSimpleTypeUnmarshall, /* FC_ENUM32 */ - NdrSimpleTypeUnmarshall, /* FC_IGNORE */ - NULL, /* FC_ERROR_STATUS_T */ - NULL, /* FC_RP */ - NULL, /* FC_UP */ - NULL, /* FC_OP */ - NULL, /* FC_FP */ - NULL, /* FC_STRUCT */ - NULL, /* FC_PSTRUCT */ - NULL, /* FC_CSTRUCT */ - NULL, /* FC_CPSTRUCT */ - NULL, /* FC_CVSTRUCT */ - NULL, /* FC_BOGUS_STRUCT */ - NULL, /* FC_CARRAY */ - NULL, /* FC_CVARRAY */ - NULL, /* FC_SMFARRAY */ - NULL, /* FC_LGFARRAY */ - NULL, /* FC_SMVARRAY */ - NULL, /* FC_LGVARRAY */ - NULL, /* FC_BOGUS_ARRAY */ - NULL, /* FC_C_CSTRING */ - NULL, /* FC_C_BSTRING */ - NULL, /* FC_C_SSTRING */ - NULL, /* FC_C_WSTRING */ - NULL, /* FC_CSTRING */ - NULL, /* FC_BSTRING */ - NULL, /* FC_SSTRING */ - NULL, /* FC_WSTRING */ - NULL, /* FC_ENCAPSULATED_UNION */ - NULL, /* FC_NON_ENCAPSULATED_UNION */ - NULL, /* FC_BYTE_COUNT_POINTER */ - NULL, /* FC_TRANSMIT_AS */ - NULL, /* FC_REPRESENT_AS */ - NULL, /* FC_IP */ - NULL, /* FC_BIND_CONTEXT */ - NULL, /* FC_BIND_GENERIC */ - NULL, /* FC_BIND_PRIMITIVE */ - NULL, /* FC_AUTO_HANDLE */ - NULL, /* FC_CALLBACK_HANDLE */ - NULL, /* FC_UNUSED1 */ - NULL, /* FC_POINTER */ - NULL, /* FC_ALIGNM2 */ - NULL, /* FC_ALIGNM4 */ - NULL, /* FC_ALIGNM8 */ - NULL, /* FC_UNUSED2 */ - NULL, /* FC_UNUSED3 */ - NULL, /* FC_UNUSED4 */ - NULL, /* FC_STRUCTPAD1 */ - NULL, /* FC_STRUCTPAD2 */ - NULL, /* FC_STRUCTPAD3 */ - NULL, /* FC_STRUCTPAD4 */ - NULL, /* FC_STRUCTPAD5 */ - NULL, /* FC_STRUCTPAD6 */ - NULL, /* FC_STRUCTPAD7 */ - NULL, /* FC_STRING_SIZED */ - NULL, /* FC_UNUSED5 */ - NULL, /* FC_NO_REPEAT */ - NULL, /* FC_FIXED_REPEAT */ - NULL, /* FC_VARIABLE_REPEAT */ - NULL, /* FC_FIXED_OFFSET */ - NULL, /* FC_VARIABLE_OFFSET */ - NULL, /* FC_PP */ - NULL, /* FC_EMBEDDED_COMPLEX */ - NULL, /* FC_IN_PARAM */ - NULL, /* FC_IN_PARAM_BASETYPE */ - NULL, /* FC_IN_PARAM_NO_FREE_INST */ - NULL, /* FC_IN_OUT_PARAM */ - NULL, /* FC_OUT_PARAM */ - NULL, /* FC_RETURN_PARAM */ - NULL, /* FC_RETURN_PARAM_BASETYPE */ - NULL, /* FC_DEREFERENCE */ - NULL, /* FC_DIV_2 */ - NULL, /* FC_MULT_2 */ - NULL, /* FC_ADD_1 */ - NULL, /* FC_SUB_1 */ - NULL, /* FC_CALLBACK */ - NULL, /* FC_CONSTANT_IID */ - NULL, /* FC_END */ - NULL, /* FC_PAD */ -}; - -const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = -{ - NULL, /* FC_ZERO */ - NdrSimpleTypeFree, /* FC_BYTE */ - NdrSimpleTypeFree, /* FC_CHAR */ - NdrSimpleTypeFree, /* FC_SMALL */ - NdrSimpleTypeFree, /* FC_USMALL */ - NdrSimpleTypeFree, /* FC_WCHAR */ - NdrSimpleTypeFree, /* FC_SHORT */ - NdrSimpleTypeFree, /* FC_USHORT */ - NdrSimpleTypeFree, /* FC_LONG */ - NdrSimpleTypeFree, /* FC_ULONG */ - NdrSimpleTypeFree, /* FC_FLOAT */ - NdrSimpleTypeFree, /* FC_HYPER */ - NdrSimpleTypeFree, /* FC_DOUBLE */ - NdrSimpleTypeFree, /* FC_ENUM16 */ - NdrSimpleTypeFree, /* FC_ENUM32 */ - NdrSimpleTypeFree, /* FC_IGNORE */ - NULL, /* FC_ERROR_STATUS_T */ - NULL, /* FC_RP */ - NULL, /* FC_UP */ - NULL, /* FC_OP */ - NULL, /* FC_FP */ - NULL, /* FC_STRUCT */ - NULL, /* FC_PSTRUCT */ - NULL, /* FC_CSTRUCT */ - NULL, /* FC_CPSTRUCT */ - NULL, /* FC_CVSTRUCT */ - NULL, /* FC_BOGUS_STRUCT */ - NULL, /* FC_CARRAY */ - NULL, /* FC_CVARRAY */ - NULL, /* FC_SMFARRAY */ - NULL, /* FC_LGFARRAY */ - NULL, /* FC_SMVARRAY */ - NULL, /* FC_LGVARRAY */ - NULL, /* FC_BOGUS_ARRAY */ - NULL, /* FC_C_CSTRING */ - NULL, /* FC_C_BSTRING */ - NULL, /* FC_C_SSTRING */ - NULL, /* FC_C_WSTRING */ - NULL, /* FC_CSTRING */ - NULL, /* FC_BSTRING */ - NULL, /* FC_SSTRING */ - NULL, /* FC_WSTRING */ - NULL, /* FC_ENCAPSULATED_UNION */ - NULL, /* FC_NON_ENCAPSULATED_UNION */ - NULL, /* FC_BYTE_COUNT_POINTER */ - NULL, /* FC_TRANSMIT_AS */ - NULL, /* FC_REPRESENT_AS */ - NULL, /* FC_IP */ - NULL, /* FC_BIND_CONTEXT */ - NULL, /* FC_BIND_GENERIC */ - NULL, /* FC_BIND_PRIMITIVE */ - NULL, /* FC_AUTO_HANDLE */ - NULL, /* FC_CALLBACK_HANDLE */ - NULL, /* FC_UNUSED1 */ - NULL, /* FC_POINTER */ - NULL, /* FC_ALIGNM2 */ - NULL, /* FC_ALIGNM4 */ - NULL, /* FC_ALIGNM8 */ - NULL, /* FC_UNUSED2 */ - NULL, /* FC_UNUSED3 */ - NULL, /* FC_UNUSED4 */ - NULL, /* FC_STRUCTPAD1 */ - NULL, /* FC_STRUCTPAD2 */ - NULL, /* FC_STRUCTPAD3 */ - NULL, /* FC_STRUCTPAD4 */ - NULL, /* FC_STRUCTPAD5 */ - NULL, /* FC_STRUCTPAD6 */ - NULL, /* FC_STRUCTPAD7 */ - NULL, /* FC_STRING_SIZED */ - NULL, /* FC_UNUSED5 */ - NULL, /* FC_NO_REPEAT */ - NULL, /* FC_FIXED_REPEAT */ - NULL, /* FC_VARIABLE_REPEAT */ - NULL, /* FC_FIXED_OFFSET */ - NULL, /* FC_VARIABLE_OFFSET */ - NULL, /* FC_PP */ - NULL, /* FC_EMBEDDED_COMPLEX */ - NULL, /* FC_IN_PARAM */ - NULL, /* FC_IN_PARAM_BASETYPE */ - NULL, /* FC_IN_PARAM_NO_FREE_INST */ - NULL, /* FC_IN_OUT_PARAM */ - NULL, /* FC_OUT_PARAM */ - NULL, /* FC_RETURN_PARAM */ - NULL, /* FC_RETURN_PARAM_BASETYPE */ - NULL, /* FC_DEREFERENCE */ - NULL, /* FC_DIV_2 */ - NULL, /* FC_MULT_2 */ - NULL, /* FC_ADD_1 */ - NULL, /* FC_SUB_1 */ - NULL, /* FC_CALLBACK */ - NULL, /* FC_CONSTANT_IID */ - NULL, /* FC_END */ - NULL, /* FC_PAD */ -}; - -char SimpleTypeAlignment[] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x01, 0x03, 0x03, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -char SimpleTypeBufferSize[] = -{ - 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -char SimpleTypeMemorySize[] = -{ - 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, - 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, - 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, - 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, -}; - -char NdrTypeFlags[] = -{ - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x02, 0x02, 0x02, 0x02, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xA0, 0xA0, 0x00, 0xC0, 0xC0, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x84, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, - 0x03, 0x10, 0x01, 0x03, 0x2C, 0x01, 0x03, 0xE0, 0x90, 0x90, 0x8B, 0x57, 0x83, 0xE7, 0x6C, 0x01, - 0x09, 0x70, 0x3B, 0x86, 0x00, 0x0F, 0x01, 0x5A, 0x00, 0x80, 0x00, 0x30, 0x8D, 0x30, 0x84, 0x00, - 0x48, 0x6A, 0x00, 0x6A, 0x01, 0x06, 0xFF, 0x08, 0x5D, 0x90, 0x7D, 0x7D, 0x0F, 0x67, 0xBD, 0xAD, - 0xAD, 0xAD, 0x9B, 0xBA, 0x9B, 0x9B, 0x0D, 0xB9, 0xAD, 0x19, 0x19, 0xBA, 0xDB, 0x09, 0x86, 0xB1, -}; - -static void NdrpAlignLength(unsigned long* length, unsigned int alignment) -{ - *length = (*length + alignment - 1) & ~(alignment - 1); -} - -static void NdrpIncrementLength(unsigned long* length, unsigned int size) -{ - *length += size; -} - -char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar) -{ - return SimpleTypeAlignment[FormatChar]; -} - -char NdrGetSimpleTypeBufferSize(unsigned char FormatChar) -{ - return SimpleTypeAlignment[FormatChar]; -} - -char NdrGetSimpleTypeMemorySize(unsigned char FormatChar) -{ - return SimpleTypeMemorySize[FormatChar]; -} - -int NdrGetTypeFlags(unsigned char FormatChar) -{ - return NdrTypeFlags[FormatChar]; -} - -/** - * Pointer Layout: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374376/ - * - * pointer_layout<>: - * - * FC_PP - * FC_PAD - * { pointer_instance_layout<> }* - * FC_END - * - * pointer_instance<8>: - * - * offset_to_pointer_in_memory<2> - * offset_to_pointer_in_buffer<2> - * pointer_description<4> - * - */ - -PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat) -{ - pFormat += 2; - - while (*pFormat != FC_END) - { - if (*pFormat == FC_NO_REPEAT) - { - /** - * FC_NO_REPEAT - * FC_PAD - * pointer_instance<8> - */ - - pFormat += 10; - } - else if (*pFormat == FC_FIXED_REPEAT) - { - unsigned short number_of_pointers; - - /** - * FC_FIXED_REPEAT - * FC_PAD - * iterations<2> - * increment<2> - * offset_to_array<2> - * number_of_pointers<2> - * { pointer_instance<8> }* - */ - - pFormat += 8; - number_of_pointers = *(unsigned short*) pFormat; - pFormat += 2 + (number_of_pointers * 8); - } - else if (*pFormat == FC_VARIABLE_REPEAT) - { - unsigned short number_of_pointers; - - /** - * FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET) - * FC_PAD ?! - * increment<2> - * offset_to_array<2> - * number_of_pointers<2> - * { pointer_instance<8> }* - */ - - pFormat += 6; - number_of_pointers = *(unsigned short*) pFormat; - pFormat += 2 + (number_of_pointers * 8); - } - else - { - printf("error: NdrpSkipPointerLayout unexpected 0x%02X\n", *pFormat); - break; - } - } - - return pFormat + 1; -} - -/* - * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/ - * - * correlation_type<1> - * correlation_operator<1> - * offset<2> - * [robust_flags<2>] - * - */ - -PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount) -{ - LPVOID ptr = NULL; - ULONG_PTR data = 0; - unsigned char type; - unsigned short offset; - unsigned char conformance; - unsigned char correlation_type; - unsigned char correlation_operator; - - correlation_type = pFormat[0]; - type = correlation_type & 0x0F; - conformance = correlation_type & 0xF0; - - correlation_operator = pFormat[1]; - offset = *(unsigned short*) & pFormat[2]; - - if (conformance == FC_NORMAL_CONFORMANCE) - { - ptr = pMemory; - } - else if (conformance == FC_POINTER_CONFORMANCE) - { - ptr = pStubMsg->Memory; - } - else if (conformance == FC_TOP_LEVEL_CONFORMANCE) - { - ptr = pStubMsg->StackTop; - } - else if (conformance == FC_CONSTANT_CONFORMANCE ) - { - data = offset | ((DWORD) pFormat[1] << 16); - *pCount = data; - } - else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE) - { - if (pStubMsg->StackTop) - ptr = pStubMsg->StackTop; - } - - switch (correlation_operator) - { - case FC_DEREFERENCE: - ptr = *(LPVOID*)((char*) ptr + offset); - break; - - case FC_DIV_2: - ptr = (char*) ptr + offset; - break; - - case FC_MULT_2: - ptr = (char*) ptr + offset; - break; - - case FC_SUB_1: - ptr = (char*) ptr + offset; - break; - - case FC_ADD_1: - ptr = (char*) ptr + offset; - break; - - case FC_CALLBACK: - { - printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n"); - } - break; - } - - switch (type) - { - case FC_LONG: - data = *(LONG*) ptr; - break; - - case FC_ULONG: - data = *(ULONG*) ptr; - break; - - case FC_SHORT: - data = *(SHORT*) ptr; - break; - - case FC_USHORT: - data = *(USHORT*) ptr; - break; - - case FC_CHAR: - case FC_SMALL: - data = *(CHAR*) ptr; - break; - - case FC_BYTE: - case FC_USMALL: - data = *(BYTE*) ptr; - break; - - case FC_HYPER: - data = (ULONG_PTR) *(ULONGLONG*) ptr; - break; - } - - switch (correlation_operator) - { - case FC_ZERO: - case FC_DEREFERENCE: - *pCount = data; - break; - - case FC_DIV_2: - *pCount = data / 1; - break; - - case FC_MULT_2: - *pCount = data * 1; - break; - - case FC_SUB_1: - *pCount = data - 1; - break; - - case FC_ADD_1: - *pCount = data + 1; - break; - - case FC_CALLBACK: - break; - } - - if (pStubMsg->fHasNewCorrDesc) - pFormat += 6; - else - pFormat += 4; - - return pFormat; -} - -PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount); -} - -PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - ULONG_PTR ActualCount = pStubMsg->ActualCount; - - pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount); - pStubMsg->ActualCount = (ULONG) ActualCount; - - return pFormat; -} - -void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - switch (*pFormat) - { - case FC_BYTE: - case FC_CHAR: - case FC_SMALL: - case FC_USMALL: - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE)); - break; - - case FC_WCHAR: - case FC_SHORT: - case FC_USHORT: - case FC_ENUM16: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(USHORT)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT)); - break; - - case FC_LONG: - case FC_ULONG: - case FC_ENUM32: - case FC_INT3264: - case FC_UINT3264: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONG)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG)); - break; - - case FC_FLOAT: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); - break; - - case FC_DOUBLE: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); - break; - - case FC_HYPER: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); - break; - - case FC_ERROR_STATUS_T: - NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); - NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); - break; - - case FC_IGNORE: - break; - } -} - -/* Pointers: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802750/ */ - -/** - * pointer_type<1> - * pointer_attributes<1> - * simple_type<1> - * FC_PAD - */ - -/** - * pointer_type<1> - * pointer_attributes<1> - * offset_to_complex_description<2> - */ - -void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg) -{ - unsigned char type; - unsigned char attributes; - PFORMAT_STRING pNextFormat; - NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine; - - type = pFormat[0]; - attributes = pFormat[1]; - pFormat += 2; - - if (attributes & FC_SIMPLE_POINTER) - pNextFormat = pFormat; - else - pNextFormat = pFormat + *(SHORT*) pFormat; - - switch (type) - { - case FC_RP: /* Reference Pointer */ - break; - - case FC_UP: /* Unique Pointer */ - case FC_OP: /* Unique Pointer in an object interface */ - - if (!pMemory) - return; - - break; - - case FC_FP: /* Full Pointer */ - printf("warning: FC_FP unimplemented\n"); - break; - } - - if (attributes & FC_POINTER_DEREF) - pMemory = *(unsigned char**) pMemory; - - pfnSizeRoutine = pfnSizeRoutines[*pNextFormat]; - - if (pfnSizeRoutine) - pfnSizeRoutine(pStubMsg, pMemory, pNextFormat); -} - -PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory) -{ - ULONG_PTR MaxCount; - unsigned char* Memory; - unsigned char* MemoryCopy; - unsigned char* MemoryPointer; - PFORMAT_STRING pFormatNext; - PFORMAT_STRING pFormatPointers; - unsigned short increment; - unsigned short pointer_count; - unsigned short offset_to_array; - unsigned short number_of_pointers; - - Memory = pStubMsg->Memory; - MemoryCopy = pStubMsg->Memory; - - if (*pFormat == FC_FIXED_REPEAT) - { - pFormat += 2; - MaxCount = *(unsigned short*) pFormat; - } - else - { - if (*pFormat != FC_VARIABLE_REPEAT) - { - RpcRaiseException(1766); - return pFormat; - } - - MaxCount = pStubMsg->MaxCount; - - if (pFormat[1] == FC_VARIABLE_OFFSET) - { - pMemory += pStubMsg->Offset * *((unsigned short*) &pFormat[1]); - } - } - - pFormat += 2; - increment = *(unsigned short*) pFormat; - - pFormat += 2; - offset_to_array = *(unsigned short*) pFormat; - pStubMsg->Memory = Memory + offset_to_array; - - pFormat += 2; - number_of_pointers = *(unsigned short*) pFormat; - - pFormat += 2; - - pFormatPointers = pFormat; - - if (MaxCount) - { - do - { - MaxCount--; - pFormatNext = pFormatPointers; - pointer_count = number_of_pointers; - - if (number_of_pointers) - { - do - { - pointer_count--; - MemoryPointer = &pMemory[*(unsigned short*) pFormatNext]; - NdrpPointerBufferSize(MemoryPointer, pFormatNext + 4, pStubMsg); - pFormatNext += 8; - } - while (pointer_count); - } - - pMemory += increment; - pStubMsg->Memory += increment; - } - while (MaxCount); - - Memory = MemoryCopy; - } - - pFormat = pFormatPointers + (number_of_pointers * 8); - pStubMsg->Memory = Memory; - - return pFormat; -} - -PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - ULONG_PTR MaxCount; - unsigned long Offset; - unsigned char* Memory; - char PointerLengthSet; - PFORMAT_STRING pFormatCopy; - unsigned long BufferLength; - unsigned long BufferLengthCopy; - unsigned long PointerLength; - unsigned char* pMemoryPtr = NULL; - - pFormatCopy = pFormat; - - if (!pStubMsg->IgnoreEmbeddedPointers) - { - PointerLength = pStubMsg->PointerLength; - PointerLengthSet = (PointerLength != 0); - - if (PointerLengthSet) - { - BufferLength = pStubMsg->BufferLength; - pStubMsg->PointerLength = 0; - BufferLengthCopy = BufferLength; - pStubMsg->BufferLength = PointerLength; - } - - MaxCount = pStubMsg->MaxCount; - Offset = pStubMsg->Offset; - Memory = pStubMsg->Memory; - pStubMsg->Memory = pMemory; - pFormat = pFormatCopy + 2; - - while (*pFormat != FC_END) - { - if (*pFormat == FC_NO_REPEAT) - { - NdrpPointerBufferSize(&pMemory[pFormat[2]], &pFormat[6], pStubMsg); - pFormat += 10; - } - - pStubMsg->Offset = Offset; - pStubMsg->MaxCount = MaxCount; - - NdrpEmbeddedRepeatPointerBufferSize(pStubMsg, pMemory, pFormat, &pMemoryPtr); - } - - pStubMsg->Memory = Memory; - - if (PointerLengthSet) - { - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = BufferLengthCopy; - } - } - - return pFormat; -} - -void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - if (*pFormat != FC_RP) - { - NdrpAlignLength((&pStubMsg->BufferLength), 4); - NdrpIncrementLength((&pStubMsg->BufferLength), 4); - } - - NdrpPointerBufferSize(pMemory, pFormat, pStubMsg); -} - -/* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */ - -void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_STRUCT - * alignment<1> - * memory_size<2> - * member_layout<> - * FC_END - */ - - /** - * FC_PSTRUCT - * alignment<1> - * memory_size<2> - * pointer_layout<> - * member_layout<> - * FC_END - */ - - unsigned char type; - unsigned char alignment; - unsigned short memory_size; - - type = pFormat[0]; - alignment = pFormat[1] + 1; - memory_size = *(unsigned short*) &pFormat[2]; - - NdrpAlignLength(&(pStubMsg->BufferLength), alignment); - NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size); - - pFormat += 4; - - if (*pFormat == FC_PSTRUCT) - NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); - - printf("warning: NdrSimpleStructBufferSize unimplemented\n"); -} - -void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_CSTRUCT alignment<1> - * memory_size<2> - * offset_to_array_description<2> - * member_layout<> - * FC_END - */ - - /** - * FC_CPSTRUCT alignment<1> - * memory_size<2> - * offset_to_array_description<2> - * pointer_layout<> - * member_layout<> FC_END - */ - - printf("warning: NdrConformantStructBufferSize unimplemented\n"); -} - -void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_CVSTRUCT alignment<1> - * memory_size<2> - * offset_to_array_description<2> - * [pointer_layout<>] - * layout<> - * FC_END - */ - - printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n"); -} - -ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) -{ - ULONG size = 0; - - while (*pFormat != FC_END) - { - switch (*pFormat) - { - case FC_BYTE: - case FC_CHAR: - case FC_SMALL: - case FC_USMALL: - size += sizeof(BYTE); - break; - - case FC_WCHAR: - case FC_SHORT: - case FC_USHORT: - case FC_ENUM16: - size += sizeof(USHORT); - break; - - case FC_LONG: - case FC_ULONG: - case FC_ENUM32: - size += sizeof(ULONG); - break; - - case FC_INT3264: - case FC_UINT3264: - size += sizeof(INT_PTR); - break; - - case FC_FLOAT: - size += sizeof(FLOAT); - break; - - case FC_DOUBLE: - size += sizeof(DOUBLE); - break; - - case FC_HYPER: - size += sizeof(ULONGLONG); - break; - - case FC_ERROR_STATUS_T: - size += sizeof(error_status_t); - break; - - case FC_IGNORE: - break; - - case FC_RP: - case FC_UP: - case FC_OP: - case FC_FP: - case FC_POINTER: - size += sizeof(void*); - if (*pFormat != FC_POINTER) - pFormat += 4; - break; - - case FC_ALIGNM2: - NdrpAlignLength(&size, 2); - break; - - case FC_ALIGNM4: - NdrpAlignLength(&size, 4); - break; - - case FC_ALIGNM8: - NdrpAlignLength(&size, 8); - break; - - case FC_STRUCTPAD1: - case FC_STRUCTPAD2: - case FC_STRUCTPAD3: - case FC_STRUCTPAD4: - case FC_STRUCTPAD5: - case FC_STRUCTPAD6: - case FC_STRUCTPAD7: - size += *pFormat - FC_STRUCTPAD1 + 1; - break; - - case FC_PAD: - break; - - case FC_EMBEDDED_COMPLEX: - printf("warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented\n"); - break; - - default: - printf("warning: NdrComplexStructMemberSize 0x%02X unimplemented\n", *pFormat); - break; - } - - pFormat++; - } - - return size; -} - -void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_BOGUS_STRUCT - * alignment<1> - * memory_size<2> - * offset_to_conformant_array_description<2> - * offset_to_pointer_layout<2> - * member_layout<> - * FC_END - * [pointer_layout<>] - */ - - ULONG_PTR MaxCount; - unsigned long Offset; - unsigned long ActualCount; - unsigned char* pMemoryCopy; - - unsigned char type; - unsigned char alignment; - unsigned short memory_size; - unsigned char* pointer_layout; - unsigned char* conformant_array_description; - unsigned short offset_to_pointer_layout; - unsigned short offset_to_conformant_array_description; - - type = pFormat[0]; - pMemoryCopy = pMemory; - pointer_layout = conformant_array_description = NULL; - - if (type != FC_BOGUS_STRUCT) - { - printf("error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type); - return; - } - - alignment = pFormat[1] + 1; - memory_size = *(unsigned short*) &pFormat[2]; - - NdrpAlignLength(&(pStubMsg->BufferLength), alignment); - - if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) - { - unsigned long BufferLengthCopy = pStubMsg->BufferLength; - int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers; - - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); - pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy; - - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = BufferLengthCopy; - } - - pFormat += 4; - - offset_to_conformant_array_description = *(unsigned short*) &pFormat[0]; - - if (offset_to_conformant_array_description) - conformant_array_description = (unsigned char*) pFormat + offset_to_conformant_array_description; - pFormat += 2; - - offset_to_pointer_layout = *(unsigned short*) &pFormat[0]; - - if (offset_to_pointer_layout) - pointer_layout = (unsigned char*) pFormat + offset_to_pointer_layout; - pFormat += 2; - - pStubMsg->Memory = pMemory; - - if (conformant_array_description) - { - ULONG size; - unsigned char array_type; - - array_type = conformant_array_description[0]; - size = NdrComplexStructMemberSize(pStubMsg, pFormat); - - printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); - - NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description); - NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description); - - MaxCount = pStubMsg->MaxCount; - ActualCount = pStubMsg->ActualCount; - Offset = pStubMsg->Offset; - } - - if (conformant_array_description) - { - unsigned char array_type; - - array_type = conformant_array_description[0]; - - pStubMsg->MaxCount = MaxCount; - pStubMsg->ActualCount = ActualCount; - pStubMsg->Offset = Offset; - - printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); - } - - pStubMsg->Memory = pMemoryCopy; - - if (pStubMsg->PointerLength > 0) - { - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - } -} - -void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_CARRAY - * alignment<1> - * element_size<2> - * conformance_description<> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - unsigned char type; - unsigned char alignment; - unsigned short element_size; - - type = pFormat[0]; - alignment = pFormat[1] + 1; - element_size = *(unsigned short*) &pFormat[2]; - - if (type != FC_CARRAY) - { - printf("error: expected FC_CARRAY, got 0x%02X\n", type); - return; - } - - printf("warning: NdrConformantArrayBufferSize unimplemented\n"); -} - -void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_CVARRAY - * alignment<1> - * element_size<2> - * conformance_description<> - * variance_description<> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - printf("warning: NdrConformantVaryingArrayBufferSize unimplemented\n"); -} - -void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_SMFARRAY - * alignment<1> - * total_size<2> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - /** - * FC_LGFARRAY - * alignment<1> - * total_size<4> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - printf("warning: NdrFixedArrayBufferSize unimplemented\n"); -} - -void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_SMVARRAY - * alignment<1> - * total_size<2> - * number_elements<2> - * element_size<2> - * variance_description<> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - /** - * FC_LGVARRAY - * alignment<1> - * total_size<4> - * number_elements<4> - * element_size<2> - * variance_description<4> - * [pointer_layout<>] - * element_description<> - * FC_END - */ - - printf("warning: NdrVaryingArrayBufferSize unimplemented\n"); -} - -void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - /** - * FC_BOGUS_ARRAY - * alignment<1> - * number_of_elements<2> - * conformance_description<> - * variance_description<> - * element_description<> - * FC_END - */ - - printf("warning: NdrComplexArrayBufferSize unimplemented\n"); -} - -void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - printf("warning: NdrConformantStringBufferSize unimplemented\n"); -} - -void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - printf("warning: NdrNonConformantStringBufferSize unimplemented\n"); -} - -void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - printf("warning: NdrEncapsulatedUnionBufferSize unimplemented\n"); -} - -void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - printf("warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n"); -} - -void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - printf("warning: NdrByteCountPointerBufferSize unimplemented\n"); -} - -void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - unsigned char type = *pFormat; - - if (type == FC_BIND_PRIMITIVE) - { - /** - * FC_BIND_PRIMITIVE - * flag<1> - * offset<2> - */ - - printf("warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented\n"); - } - else if (type == FC_BIND_GENERIC) - { - /** - * FC_BIND_GENERIC - * flag_and_size<1> - * offset<2> - * binding_routine_pair_index<1> - * FC_PAD - */ - - printf("warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented\n"); - } - else if (type == FC_BIND_CONTEXT) - { - /** - * FC_BIND_CONTEXT - * flags<1> - * offset<2> - * context_rundown_routine_index<1> - * param_num<1> - */ - - NdrpAlignLength(&(pStubMsg->BufferLength), 4); - NdrpIncrementLength(&(pStubMsg->BufferLength), 20); - } -} - -void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) -{ - -} - -void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) -{ - -} - -void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - -} - void NdrPrintParamAttributes(PARAM_ATTRIBUTES attributes) { if (attributes.ServerAllocSize) diff --git a/libwinpr-rpc/ndr_array.c b/libwinpr-rpc/ndr_array.c new file mode 100644 index 000000000..3c800144d --- /dev/null +++ b/libwinpr-rpc/ndr_array.c @@ -0,0 +1,137 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "ndr_array.h" + +void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CARRAY + * alignment<1> + * element_size<2> + * conformance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + unsigned char type; + unsigned char alignment; + unsigned short element_size; + + type = pFormat[0]; + alignment = pFormat[1] + 1; + element_size = *(unsigned short*) &pFormat[2]; + + if (type != FC_CARRAY) + { + printf("error: expected FC_CARRAY, got 0x%02X\n", type); + return; + } + + printf("warning: NdrConformantArrayBufferSize unimplemented\n"); +} + +void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CVARRAY + * alignment<1> + * element_size<2> + * conformance_description<> + * variance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrConformantVaryingArrayBufferSize unimplemented\n"); +} + +void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_SMFARRAY + * alignment<1> + * total_size<2> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + /** + * FC_LGFARRAY + * alignment<1> + * total_size<4> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrFixedArrayBufferSize unimplemented\n"); +} + +void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_SMVARRAY + * alignment<1> + * total_size<2> + * number_elements<2> + * element_size<2> + * variance_description<> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + /** + * FC_LGVARRAY + * alignment<1> + * total_size<4> + * number_elements<4> + * element_size<2> + * variance_description<4> + * [pointer_layout<>] + * element_description<> + * FC_END + */ + + printf("warning: NdrVaryingArrayBufferSize unimplemented\n"); +} + +void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_BOGUS_ARRAY + * alignment<1> + * number_of_elements<2> + * conformance_description<> + * variance_description<> + * element_description<> + * FC_END + */ + + printf("warning: NdrComplexArrayBufferSize unimplemented\n"); +} diff --git a/libwinpr-rpc/ndr_array.h b/libwinpr-rpc/ndr_array.h new file mode 100644 index 000000000..3a6bc2d44 --- /dev/null +++ b/libwinpr-rpc/ndr_array.h @@ -0,0 +1,31 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_ARRAY_H +#define WINPR_RPC_NDR_ARRAY_H + +#include + +void NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrConformantVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_ARRAY_H */ diff --git a/libwinpr-rpc/ndr_context.c b/libwinpr-rpc/ndr_context.c new file mode 100644 index 000000000..270074f95 --- /dev/null +++ b/libwinpr-rpc/ndr_context.c @@ -0,0 +1,66 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include "ndr_context.h" +#include "ndr_private.h" + +void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + unsigned char type = *pFormat; + + if (type == FC_BIND_PRIMITIVE) + { + /** + * FC_BIND_PRIMITIVE + * flag<1> + * offset<2> + */ + + printf("warning: NdrContextHandleBufferSize FC_BIND_PRIMITIVE unimplemented\n"); + } + else if (type == FC_BIND_GENERIC) + { + /** + * FC_BIND_GENERIC + * flag_and_size<1> + * offset<2> + * binding_routine_pair_index<1> + * FC_PAD + */ + + printf("warning: NdrContextHandleBufferSize FC_BIND_GENERIC unimplemented\n"); + } + else if (type == FC_BIND_CONTEXT) + { + /** + * FC_BIND_CONTEXT + * flags<1> + * offset<2> + * context_rundown_routine_index<1> + * param_num<1> + */ + + NdrpAlignLength(&(pStubMsg->BufferLength), 4); + NdrpIncrementLength(&(pStubMsg->BufferLength), 20); + } +} diff --git a/libwinpr-rpc/ndr_context.h b/libwinpr-rpc/ndr_context.h new file mode 100644 index 000000000..7b8770c2a --- /dev/null +++ b/libwinpr-rpc/ndr_context.h @@ -0,0 +1,27 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_CONTEXT_H +#define WINPR_RPC_NDR_CONTEXT_H + +#include + +void NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_CONTEXT_H */ diff --git a/libwinpr-rpc/ndr_correlation.c b/libwinpr-rpc/ndr_correlation.c new file mode 100644 index 000000000..1a9383403 --- /dev/null +++ b/libwinpr-rpc/ndr_correlation.c @@ -0,0 +1,187 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include "ndr_correlation.h" +#include "ndr_private.h" + +/* + * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/ + * + * correlation_type<1> + * correlation_operator<1> + * offset<2> + * [robust_flags<2>] + * + */ + +PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount) +{ + LPVOID ptr = NULL; + ULONG_PTR data = 0; + unsigned char type; + unsigned short offset; + unsigned char conformance; + unsigned char correlation_type; + unsigned char correlation_operator; + + correlation_type = pFormat[0]; + type = correlation_type & 0x0F; + conformance = correlation_type & 0xF0; + + correlation_operator = pFormat[1]; + offset = *(unsigned short*) & pFormat[2]; + + if (conformance == FC_NORMAL_CONFORMANCE) + { + ptr = pMemory; + } + else if (conformance == FC_POINTER_CONFORMANCE) + { + ptr = pStubMsg->Memory; + } + else if (conformance == FC_TOP_LEVEL_CONFORMANCE) + { + ptr = pStubMsg->StackTop; + } + else if (conformance == FC_CONSTANT_CONFORMANCE ) + { + data = offset | ((DWORD) pFormat[1] << 16); + *pCount = data; + } + else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE) + { + if (pStubMsg->StackTop) + ptr = pStubMsg->StackTop; + } + + switch (correlation_operator) + { + case FC_DEREFERENCE: + ptr = *(LPVOID*)((char*) ptr + offset); + break; + + case FC_DIV_2: + ptr = (char*) ptr + offset; + break; + + case FC_MULT_2: + ptr = (char*) ptr + offset; + break; + + case FC_SUB_1: + ptr = (char*) ptr + offset; + break; + + case FC_ADD_1: + ptr = (char*) ptr + offset; + break; + + case FC_CALLBACK: + { + printf("warning: NdrpComputeConformance FC_CALLBACK unimplemented\n"); + } + break; + } + + switch (type) + { + case FC_LONG: + data = *(LONG*) ptr; + break; + + case FC_ULONG: + data = *(ULONG*) ptr; + break; + + case FC_SHORT: + data = *(SHORT*) ptr; + break; + + case FC_USHORT: + data = *(USHORT*) ptr; + break; + + case FC_CHAR: + case FC_SMALL: + data = *(CHAR*) ptr; + break; + + case FC_BYTE: + case FC_USMALL: + data = *(BYTE*) ptr; + break; + + case FC_HYPER: + data = (ULONG_PTR) *(ULONGLONG*) ptr; + break; + } + + switch (correlation_operator) + { + case FC_ZERO: + case FC_DEREFERENCE: + *pCount = data; + break; + + case FC_DIV_2: + *pCount = data / 1; + break; + + case FC_MULT_2: + *pCount = data * 1; + break; + + case FC_SUB_1: + *pCount = data - 1; + break; + + case FC_ADD_1: + *pCount = data + 1; + break; + + case FC_CALLBACK: + break; + } + + if (pStubMsg->fHasNewCorrDesc) + pFormat += 6; + else + pFormat += 4; + + return pFormat; +} + +PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount); +} + +PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + ULONG_PTR ActualCount = pStubMsg->ActualCount; + + pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount); + pStubMsg->ActualCount = (ULONG) ActualCount; + + return pFormat; +} diff --git a/libwinpr-rpc/ndr_correlation.h b/libwinpr-rpc/ndr_correlation.h new file mode 100644 index 000000000..01724b408 --- /dev/null +++ b/libwinpr-rpc/ndr_correlation.h @@ -0,0 +1,29 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_CORRELATION_H +#define WINPR_RPC_NDR_CORRELATION_H + +#include + +PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount); +PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_CORRELATION_H */ diff --git a/libwinpr-rpc/ndr_pointer.c b/libwinpr-rpc/ndr_pointer.c new file mode 100644 index 000000000..b38dcbc3e --- /dev/null +++ b/libwinpr-rpc/ndr_pointer.c @@ -0,0 +1,322 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include "ndr_pointer.h" +#include "ndr_private.h" + +/** + * Pointer Layout: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374376/ + * + * pointer_layout<>: + * + * FC_PP + * FC_PAD + * { pointer_instance_layout<> }* + * FC_END + * + * pointer_instance<8>: + * + * offset_to_pointer_in_memory<2> + * offset_to_pointer_in_buffer<2> + * pointer_description<4> + * + */ + +PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat) +{ + pFormat += 2; + + while (*pFormat != FC_END) + { + if (*pFormat == FC_NO_REPEAT) + { + /** + * FC_NO_REPEAT + * FC_PAD + * pointer_instance<8> + */ + + pFormat += 10; + } + else if (*pFormat == FC_FIXED_REPEAT) + { + unsigned short number_of_pointers; + + /** + * FC_FIXED_REPEAT + * FC_PAD + * iterations<2> + * increment<2> + * offset_to_array<2> + * number_of_pointers<2> + * { pointer_instance<8> }* + */ + + pFormat += 8; + number_of_pointers = *(unsigned short*) pFormat; + pFormat += 2 + (number_of_pointers * 8); + } + else if (*pFormat == FC_VARIABLE_REPEAT) + { + unsigned short number_of_pointers; + + /** + * FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET) + * FC_PAD ?! + * increment<2> + * offset_to_array<2> + * number_of_pointers<2> + * { pointer_instance<8> }* + */ + + pFormat += 6; + number_of_pointers = *(unsigned short*) pFormat; + pFormat += 2 + (number_of_pointers * 8); + } + else + { + printf("error: NdrpSkipPointerLayout unexpected 0x%02X\n", *pFormat); + break; + } + } + + return pFormat + 1; +} + +/* Pointers: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802750/ */ + +/** + * pointer_type<1> + * pointer_attributes<1> + * simple_type<1> + * FC_PAD + */ + +/** + * pointer_type<1> + * pointer_attributes<1> + * offset_to_complex_description<2> + */ + +void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg) +{ + unsigned char type; + unsigned char attributes; + PFORMAT_STRING pNextFormat; + NDR_TYPE_SIZE_ROUTINE pfnSizeRoutine; + + type = pFormat[0]; + attributes = pFormat[1]; + pFormat += 2; + + if (attributes & FC_SIMPLE_POINTER) + pNextFormat = pFormat; + else + pNextFormat = pFormat + *(SHORT*) pFormat; + + switch (type) + { + case FC_RP: /* Reference Pointer */ + break; + + case FC_UP: /* Unique Pointer */ + case FC_OP: /* Unique Pointer in an object interface */ + + if (!pMemory) + return; + + break; + + case FC_FP: /* Full Pointer */ + printf("warning: FC_FP unimplemented\n"); + break; + } + + if (attributes & FC_POINTER_DEREF) + pMemory = *(unsigned char**) pMemory; + + pfnSizeRoutine = pfnSizeRoutines[*pNextFormat]; + + if (pfnSizeRoutine) + pfnSizeRoutine(pStubMsg, pMemory, pNextFormat); +} + +PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory) +{ + ULONG_PTR MaxCount; + unsigned char* Memory; + unsigned char* MemoryCopy; + unsigned char* MemoryPointer; + PFORMAT_STRING pFormatNext; + PFORMAT_STRING pFormatPointers; + unsigned short increment; + unsigned short pointer_count; + unsigned short offset_to_array; + unsigned short number_of_pointers; + + Memory = pStubMsg->Memory; + MemoryCopy = pStubMsg->Memory; + + if (*pFormat == FC_FIXED_REPEAT) + { + pFormat += 2; + MaxCount = *(unsigned short*) pFormat; + } + else + { + if (*pFormat != FC_VARIABLE_REPEAT) + { + RpcRaiseException(1766); + return pFormat; + } + + MaxCount = pStubMsg->MaxCount; + + if (pFormat[1] == FC_VARIABLE_OFFSET) + { + pMemory += pStubMsg->Offset * *((unsigned short*) &pFormat[1]); + } + } + + pFormat += 2; + increment = *(unsigned short*) pFormat; + + pFormat += 2; + offset_to_array = *(unsigned short*) pFormat; + pStubMsg->Memory = Memory + offset_to_array; + + pFormat += 2; + number_of_pointers = *(unsigned short*) pFormat; + + pFormat += 2; + + pFormatPointers = pFormat; + + if (MaxCount) + { + do + { + MaxCount--; + pFormatNext = pFormatPointers; + pointer_count = number_of_pointers; + + if (number_of_pointers) + { + do + { + pointer_count--; + MemoryPointer = &pMemory[*(unsigned short*) pFormatNext]; + NdrpPointerBufferSize(MemoryPointer, pFormatNext + 4, pStubMsg); + pFormatNext += 8; + } + while (pointer_count); + } + + pMemory += increment; + pStubMsg->Memory += increment; + } + while (MaxCount); + + Memory = MemoryCopy; + } + + pFormat = pFormatPointers + (number_of_pointers * 8); + pStubMsg->Memory = Memory; + + return pFormat; +} + +PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned char* Memory; + char PointerLengthSet; + PFORMAT_STRING pFormatCopy; + unsigned long BufferLength; + unsigned long BufferLengthCopy; + unsigned long PointerLength; + unsigned char* pMemoryPtr = NULL; + + pFormatCopy = pFormat; + + if (!pStubMsg->IgnoreEmbeddedPointers) + { + PointerLength = pStubMsg->PointerLength; + PointerLengthSet = (PointerLength != 0); + + if (PointerLengthSet) + { + BufferLength = pStubMsg->BufferLength; + pStubMsg->PointerLength = 0; + BufferLengthCopy = BufferLength; + pStubMsg->BufferLength = PointerLength; + } + + MaxCount = pStubMsg->MaxCount; + Offset = pStubMsg->Offset; + Memory = pStubMsg->Memory; + pStubMsg->Memory = pMemory; + pFormat = pFormatCopy + 2; + + while (*pFormat != FC_END) + { + if (*pFormat == FC_NO_REPEAT) + { + NdrpPointerBufferSize(&pMemory[pFormat[2]], &pFormat[6], pStubMsg); + pFormat += 10; + } + + pStubMsg->Offset = Offset; + pStubMsg->MaxCount = MaxCount; + + NdrpEmbeddedRepeatPointerBufferSize(pStubMsg, pMemory, pFormat, &pMemoryPtr); + } + + pStubMsg->Memory = Memory; + + if (PointerLengthSet) + { + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = BufferLengthCopy; + } + } + + return pFormat; +} + +void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + if (*pFormat != FC_RP) + { + NdrpAlignLength((&pStubMsg->BufferLength), 4); + NdrpIncrementLength((&pStubMsg->BufferLength), 4); + } + + NdrpPointerBufferSize(pMemory, pFormat, pStubMsg); +} + +void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrByteCountPointerBufferSize unimplemented\n"); +} diff --git a/libwinpr-rpc/ndr_pointer.h b/libwinpr-rpc/ndr_pointer.h new file mode 100644 index 000000000..3712316af --- /dev/null +++ b/libwinpr-rpc/ndr_pointer.h @@ -0,0 +1,30 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_POINTER_H +#define WINPR_RPC_NDR_POINTER_H + +#include + +PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat); + +void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_POINTER_H */ diff --git a/libwinpr-rpc/ndr_private.c b/libwinpr-rpc/ndr_private.c new file mode 100644 index 000000000..22fc59868 --- /dev/null +++ b/libwinpr-rpc/ndr_private.c @@ -0,0 +1,552 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "ndr_array.h" +#include "ndr_context.h" +#include "ndr_pointer.h" +#include "ndr_simple.h" +#include "ndr_string.h" +#include "ndr_structure.h" +#include "ndr_union.h" + +#include "ndr_private.h" + +void NdrpAlignLength(unsigned long* length, unsigned int alignment) +{ + *length = (*length + alignment - 1) & ~(alignment - 1); +} + +void NdrpIncrementLength(unsigned long* length, unsigned int size) +{ + *length += size; +} + +const char* FC_TYPE_STRINGS[] = +{ + "FC_ZERO", + "FC_BYTE", + "FC_CHAR", + "FC_SMALL", + "FC_USMALL", + "FC_WCHAR", + "FC_SHORT", + "FC_USHORT", + "FC_LONG", + "FC_ULONG", + "FC_FLOAT", + "FC_HYPER", + "FC_DOUBLE", + "FC_ENUM16", + "FC_ENUM32", + "FC_IGNORE", + "FC_ERROR_STATUS_T", + "FC_RP", + "FC_UP", + "FC_OP", + "FC_FP", + "FC_STRUCT", + "FC_PSTRUCT", + "FC_CSTRUCT", + "FC_CPSTRUCT", + "FC_CVSTRUCT", + "FC_BOGUS_STRUCT", + "FC_CARRAY", + "FC_CVARRAY", + "FC_SMFARRAY", + "FC_LGFARRAY", + "FC_SMVARRAY", + "FC_LGVARRAY", + "FC_BOGUS_ARRAY", + "FC_C_CSTRING", + "FC_C_BSTRING", + "FC_C_SSTRING", + "FC_C_WSTRING", + "FC_CSTRING", + "FC_BSTRING", + "FC_SSTRING", + "FC_WSTRING", + "FC_ENCAPSULATED_UNION", + "FC_NON_ENCAPSULATED_UNION", + "FC_BYTE_COUNT_POINTER", + "FC_TRANSMIT_AS", + "FC_REPRESENT_AS", + "FC_IP", + "FC_BIND_CONTEXT", + "FC_BIND_GENERIC", + "FC_BIND_PRIMITIVE", + "FC_AUTO_HANDLE", + "FC_CALLBACK_HANDLE", + "FC_UNUSED1", + "FC_POINTER", + "FC_ALIGNM2", + "FC_ALIGNM4", + "FC_ALIGNM8", + "FC_UNUSED2", + "FC_UNUSED3", + "FC_UNUSED4", + "FC_STRUCTPAD1", + "FC_STRUCTPAD2", + "FC_STRUCTPAD3", + "FC_STRUCTPAD4", + "FC_STRUCTPAD5", + "FC_STRUCTPAD6", + "FC_STRUCTPAD7", + "FC_STRING_SIZED", + "FC_UNUSED5", + "FC_NO_REPEAT", + "FC_FIXED_REPEAT", + "FC_VARIABLE_REPEAT", + "FC_FIXED_OFFSET", + "FC_VARIABLE_OFFSET", + "FC_PP", + "FC_EMBEDDED_COMPLEX", + "FC_IN_PARAM", + "FC_IN_PARAM_BASETYPE", + "FC_IN_PARAM_NO_FREE_INST", + "FC_IN_OUT_PARAM", + "FC_OUT_PARAM", + "FC_RETURN_PARAM", + "FC_RETURN_PARAM_BASETYPE", + "FC_DEREFERENCE", + "FC_DIV_2", + "FC_MULT_2", + "FC_ADD_1", + "FC_SUB_1", + "FC_CALLBACK", + "FC_CONSTANT_IID", + "FC_END", + "FC_PAD", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", "", "", + "FC_SPLIT_DEREFERENCE", + "FC_SPLIT_DIV_2", + "FC_SPLIT_MULT_2", + "FC_SPLIT_ADD_1", + "FC_SPLIT_SUB_1", + "FC_SPLIT_CALLBACK", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "FC_HARD_STRUCT", + "FC_TRANSMIT_AS_PTR", + "FC_REPRESENT_AS_PTR", + "FC_USER_MARSHAL", + "FC_PIPE", + "FC_BLKHOLE", + "FC_RANGE", + "FC_INT3264", + "FC_UINT3264", + "FC_END_OF_UNIVERSE", +}; + +const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeBufferSize, /* FC_BYTE */ + NdrSimpleTypeBufferSize, /* FC_CHAR */ + NdrSimpleTypeBufferSize, /* FC_SMALL */ + NdrSimpleTypeBufferSize, /* FC_USMALL */ + NdrSimpleTypeBufferSize, /* FC_WCHAR */ + NdrSimpleTypeBufferSize, /* FC_SHORT */ + NdrSimpleTypeBufferSize, /* FC_USHORT */ + NdrSimpleTypeBufferSize, /* FC_LONG */ + NdrSimpleTypeBufferSize, /* FC_ULONG */ + NdrSimpleTypeBufferSize, /* FC_FLOAT */ + NdrSimpleTypeBufferSize, /* FC_HYPER */ + NdrSimpleTypeBufferSize, /* FC_DOUBLE */ + NdrSimpleTypeBufferSize, /* FC_ENUM16 */ + NdrSimpleTypeBufferSize, /* FC_ENUM32 */ + NdrSimpleTypeBufferSize, /* FC_IGNORE */ + NdrSimpleTypeBufferSize, /* FC_ERROR_STATUS_T */ + NdrPointerBufferSize, /* FC_RP */ + NdrPointerBufferSize, /* FC_UP */ + NdrPointerBufferSize, /* FC_OP */ + NdrPointerBufferSize, /* FC_FP */ + NdrSimpleStructBufferSize, /* FC_STRUCT */ + NdrSimpleStructBufferSize, /* FC_PSTRUCT */ + NdrConformantStructBufferSize, /* FC_CSTRUCT */ + NdrConformantStructBufferSize, /* FC_CPSTRUCT */ + NdrConformantVaryingStructBufferSize, /* FC_CVSTRUCT */ + NdrComplexStructBufferSize, /* FC_BOGUS_STRUCT */ + NdrConformantArrayBufferSize, /* FC_CARRAY */ + NdrConformantVaryingArrayBufferSize, /* FC_CVARRAY */ + NdrFixedArrayBufferSize, /* FC_SMFARRAY */ + NdrFixedArrayBufferSize, /* FC_LGFARRAY */ + NdrVaryingArrayBufferSize, /* FC_SMVARRAY */ + NdrVaryingArrayBufferSize, /* FC_LGVARRAY */ + NdrComplexArrayBufferSize, /* FC_BOGUS_ARRAY */ + NdrConformantStringBufferSize, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NdrConformantStringBufferSize, /* FC_C_WSTRING */ + NdrNonConformantStringBufferSize, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NdrEncapsulatedUnionBufferSize, /* FC_ENCAPSULATED_UNION */ + NdrNonEncapsulatedUnionBufferSize, /* FC_NON_ENCAPSULATED_UNION */ + NdrByteCountPointerBufferSize, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NdrContextHandleBufferSize, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeMarshall, /* FC_BYTE */ + NdrSimpleTypeMarshall, /* FC_CHAR */ + NdrSimpleTypeMarshall, /* FC_SMALL */ + NdrSimpleTypeMarshall, /* FC_USMALL */ + NdrSimpleTypeMarshall, /* FC_WCHAR */ + NdrSimpleTypeMarshall, /* FC_SHORT */ + NdrSimpleTypeMarshall, /* FC_USHORT */ + NdrSimpleTypeMarshall, /* FC_LONG */ + NdrSimpleTypeMarshall, /* FC_ULONG */ + NdrSimpleTypeMarshall, /* FC_FLOAT */ + NdrSimpleTypeMarshall, /* FC_HYPER */ + NdrSimpleTypeMarshall, /* FC_DOUBLE */ + NdrSimpleTypeMarshall, /* FC_ENUM16 */ + NdrSimpleTypeMarshall, /* FC_ENUM32 */ + NdrSimpleTypeMarshall, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeUnmarshall, /* FC_BYTE */ + NdrSimpleTypeUnmarshall, /* FC_CHAR */ + NdrSimpleTypeUnmarshall, /* FC_SMALL */ + NdrSimpleTypeUnmarshall, /* FC_USMALL */ + NdrSimpleTypeUnmarshall, /* FC_WCHAR */ + NdrSimpleTypeUnmarshall, /* FC_SHORT */ + NdrSimpleTypeUnmarshall, /* FC_USHORT */ + NdrSimpleTypeUnmarshall, /* FC_LONG */ + NdrSimpleTypeUnmarshall, /* FC_ULONG */ + NdrSimpleTypeUnmarshall, /* FC_FLOAT */ + NdrSimpleTypeUnmarshall, /* FC_HYPER */ + NdrSimpleTypeUnmarshall, /* FC_DOUBLE */ + NdrSimpleTypeUnmarshall, /* FC_ENUM16 */ + NdrSimpleTypeUnmarshall, /* FC_ENUM32 */ + NdrSimpleTypeUnmarshall, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; + +const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[] = +{ + NULL, /* FC_ZERO */ + NdrSimpleTypeFree, /* FC_BYTE */ + NdrSimpleTypeFree, /* FC_CHAR */ + NdrSimpleTypeFree, /* FC_SMALL */ + NdrSimpleTypeFree, /* FC_USMALL */ + NdrSimpleTypeFree, /* FC_WCHAR */ + NdrSimpleTypeFree, /* FC_SHORT */ + NdrSimpleTypeFree, /* FC_USHORT */ + NdrSimpleTypeFree, /* FC_LONG */ + NdrSimpleTypeFree, /* FC_ULONG */ + NdrSimpleTypeFree, /* FC_FLOAT */ + NdrSimpleTypeFree, /* FC_HYPER */ + NdrSimpleTypeFree, /* FC_DOUBLE */ + NdrSimpleTypeFree, /* FC_ENUM16 */ + NdrSimpleTypeFree, /* FC_ENUM32 */ + NdrSimpleTypeFree, /* FC_IGNORE */ + NULL, /* FC_ERROR_STATUS_T */ + NULL, /* FC_RP */ + NULL, /* FC_UP */ + NULL, /* FC_OP */ + NULL, /* FC_FP */ + NULL, /* FC_STRUCT */ + NULL, /* FC_PSTRUCT */ + NULL, /* FC_CSTRUCT */ + NULL, /* FC_CPSTRUCT */ + NULL, /* FC_CVSTRUCT */ + NULL, /* FC_BOGUS_STRUCT */ + NULL, /* FC_CARRAY */ + NULL, /* FC_CVARRAY */ + NULL, /* FC_SMFARRAY */ + NULL, /* FC_LGFARRAY */ + NULL, /* FC_SMVARRAY */ + NULL, /* FC_LGVARRAY */ + NULL, /* FC_BOGUS_ARRAY */ + NULL, /* FC_C_CSTRING */ + NULL, /* FC_C_BSTRING */ + NULL, /* FC_C_SSTRING */ + NULL, /* FC_C_WSTRING */ + NULL, /* FC_CSTRING */ + NULL, /* FC_BSTRING */ + NULL, /* FC_SSTRING */ + NULL, /* FC_WSTRING */ + NULL, /* FC_ENCAPSULATED_UNION */ + NULL, /* FC_NON_ENCAPSULATED_UNION */ + NULL, /* FC_BYTE_COUNT_POINTER */ + NULL, /* FC_TRANSMIT_AS */ + NULL, /* FC_REPRESENT_AS */ + NULL, /* FC_IP */ + NULL, /* FC_BIND_CONTEXT */ + NULL, /* FC_BIND_GENERIC */ + NULL, /* FC_BIND_PRIMITIVE */ + NULL, /* FC_AUTO_HANDLE */ + NULL, /* FC_CALLBACK_HANDLE */ + NULL, /* FC_UNUSED1 */ + NULL, /* FC_POINTER */ + NULL, /* FC_ALIGNM2 */ + NULL, /* FC_ALIGNM4 */ + NULL, /* FC_ALIGNM8 */ + NULL, /* FC_UNUSED2 */ + NULL, /* FC_UNUSED3 */ + NULL, /* FC_UNUSED4 */ + NULL, /* FC_STRUCTPAD1 */ + NULL, /* FC_STRUCTPAD2 */ + NULL, /* FC_STRUCTPAD3 */ + NULL, /* FC_STRUCTPAD4 */ + NULL, /* FC_STRUCTPAD5 */ + NULL, /* FC_STRUCTPAD6 */ + NULL, /* FC_STRUCTPAD7 */ + NULL, /* FC_STRING_SIZED */ + NULL, /* FC_UNUSED5 */ + NULL, /* FC_NO_REPEAT */ + NULL, /* FC_FIXED_REPEAT */ + NULL, /* FC_VARIABLE_REPEAT */ + NULL, /* FC_FIXED_OFFSET */ + NULL, /* FC_VARIABLE_OFFSET */ + NULL, /* FC_PP */ + NULL, /* FC_EMBEDDED_COMPLEX */ + NULL, /* FC_IN_PARAM */ + NULL, /* FC_IN_PARAM_BASETYPE */ + NULL, /* FC_IN_PARAM_NO_FREE_INST */ + NULL, /* FC_IN_OUT_PARAM */ + NULL, /* FC_OUT_PARAM */ + NULL, /* FC_RETURN_PARAM */ + NULL, /* FC_RETURN_PARAM_BASETYPE */ + NULL, /* FC_DEREFERENCE */ + NULL, /* FC_DIV_2 */ + NULL, /* FC_MULT_2 */ + NULL, /* FC_ADD_1 */ + NULL, /* FC_SUB_1 */ + NULL, /* FC_CALLBACK */ + NULL, /* FC_CONSTANT_IID */ + NULL, /* FC_END */ + NULL, /* FC_PAD */ +}; diff --git a/libwinpr-rpc/ndr_private.h b/libwinpr-rpc/ndr_private.h new file mode 100644 index 000000000..d5eb947b1 --- /dev/null +++ b/libwinpr-rpc/ndr_private.h @@ -0,0 +1,42 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_PRIVATE_H +#define WINPR_RPC_NDR_PRIVATE_H + +#include + +void NdrpAlignLength(unsigned long* length, unsigned int alignment); +void NdrpIncrementLength(unsigned long* length, unsigned int size); + +extern const NDR_TYPE_SIZE_ROUTINE pfnSizeRoutines[]; +extern const NDR_TYPE_MARSHALL_ROUTINE pfnMarshallRoutines[]; +extern const NDR_TYPE_UNMARSHALL_ROUTINE pfnUnmarshallRoutines[]; +extern const NDR_TYPE_FREE_ROUTINE pfnFreeRoutines[]; + +extern const char SimpleTypeAlignment[]; +extern const char SimpleTypeBufferSize[]; +extern const char SimpleTypeMemorySize[]; + +extern const char NdrTypeFlags[]; +extern const char* FC_TYPE_STRINGS[]; + +#include "ndr_correlation.h" + +#endif /* WINPR_RPC_NDR_PRIVATE_H */ diff --git a/libwinpr-rpc/ndr_simple.c b/libwinpr-rpc/ndr_simple.c new file mode 100644 index 000000000..97927f19e --- /dev/null +++ b/libwinpr-rpc/ndr_simple.c @@ -0,0 +1,193 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include "ndr_simple.h" +#include "ndr_private.h" + +const char SimpleTypeAlignment[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x01, 0x03, 0x03, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const char SimpleTypeBufferSize[] = +{ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x02, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const char SimpleTypeMemorySize[] = +{ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, + 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, 0x92, 0x9D, 0x3A, 0x75, +}; + +const char NdrTypeFlags[] = +{ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x02, 0x02, 0x02, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xA0, 0xA0, 0x00, 0xC0, 0xC0, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, + 0x03, 0x10, 0x01, 0x03, 0x2C, 0x01, 0x03, 0xE0, 0x90, 0x90, 0x8B, 0x57, 0x83, 0xE7, 0x6C, 0x01, + 0x09, 0x70, 0x3B, 0x86, 0x00, 0x0F, 0x01, 0x5A, 0x00, 0x80, 0x00, 0x30, 0x8D, 0x30, 0x84, 0x00, + 0x48, 0x6A, 0x00, 0x6A, 0x01, 0x06, 0xFF, 0x08, 0x5D, 0x90, 0x7D, 0x7D, 0x0F, 0x67, 0xBD, 0xAD, + 0xAD, 0xAD, 0x9B, 0xBA, 0x9B, 0x9B, 0x0D, 0xB9, 0xAD, 0x19, 0x19, 0xBA, 0xDB, 0x09, 0x86, 0xB1, +}; + +char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar) +{ + return SimpleTypeAlignment[FormatChar]; +} + +char NdrGetSimpleTypeBufferSize(unsigned char FormatChar) +{ + return SimpleTypeAlignment[FormatChar]; +} + +char NdrGetSimpleTypeMemorySize(unsigned char FormatChar) +{ + return SimpleTypeMemorySize[FormatChar]; +} + +int NdrGetTypeFlags(unsigned char FormatChar) +{ + return NdrTypeFlags[FormatChar]; +} + +void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + switch (*pFormat) + { + case FC_BYTE: + case FC_CHAR: + case FC_SMALL: + case FC_USMALL: + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(BYTE)); + break; + + case FC_WCHAR: + case FC_SHORT: + case FC_USHORT: + case FC_ENUM16: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(USHORT)); + break; + + case FC_LONG: + case FC_ULONG: + case FC_ENUM32: + case FC_INT3264: + case FC_UINT3264: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONG)); + break; + + case FC_FLOAT: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(FLOAT)); + break; + + case FC_DOUBLE: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(DOUBLE)); + break; + + case FC_HYPER: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(ULONGLONG)); + break; + + case FC_ERROR_STATUS_T: + NdrpAlignLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + NdrpIncrementLength(&(pStubMsg->BufferLength), sizeof(error_status_t)); + break; + + case FC_IGNORE: + break; + } +} + +void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) +{ + +} + +void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar) +{ + +} + +void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + +} diff --git a/libwinpr-rpc/ndr_simple.h b/libwinpr-rpc/ndr_simple.h new file mode 100644 index 000000000..bbd454209 --- /dev/null +++ b/libwinpr-rpc/ndr_simple.h @@ -0,0 +1,35 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_SIMPLE_H +#define WINPR_RPC_NDR_SIMPLE_H + +#include + +void NdrSimpleTypeBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +void NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); +void NdrSimpleTypeFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +char NdrGetSimpleTypeBufferAlignment(unsigned char FormatChar); +char NdrGetSimpleTypeBufferSize(unsigned char FormatChar); +char NdrGetSimpleTypeMemorySize(unsigned char FormatChar); +int NdrGetTypeFlags(unsigned char FormatChar); + +#endif /* WINPR_RPC_NDR_SIMPLE_H */ diff --git a/libwinpr-rpc/ndr_string.c b/libwinpr-rpc/ndr_string.c new file mode 100644 index 000000000..a52fb9923 --- /dev/null +++ b/libwinpr-rpc/ndr_string.c @@ -0,0 +1,35 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "ndr_string.h" + +void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrConformantStringBufferSize unimplemented\n"); +} + +void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrNonConformantStringBufferSize unimplemented\n"); +} diff --git a/libwinpr-rpc/ndr_string.h b/libwinpr-rpc/ndr_string.h new file mode 100644 index 000000000..cbbd63308 --- /dev/null +++ b/libwinpr-rpc/ndr_string.h @@ -0,0 +1,28 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_STRING_H +#define WINPR_RPC_NDR_STRING_H + +#include + +void NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_STRING_H */ diff --git a/libwinpr-rpc/ndr_structure.c b/libwinpr-rpc/ndr_structure.c new file mode 100644 index 000000000..849e71bd6 --- /dev/null +++ b/libwinpr-rpc/ndr_structure.c @@ -0,0 +1,313 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "ndr_structure.h" + + +/* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */ + +void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_STRUCT + * alignment<1> + * memory_size<2> + * member_layout<> + * FC_END + */ + + /** + * FC_PSTRUCT + * alignment<1> + * memory_size<2> + * pointer_layout<> + * member_layout<> + * FC_END + */ + + unsigned char type; + unsigned char alignment; + unsigned short memory_size; + + type = pFormat[0]; + alignment = pFormat[1] + 1; + memory_size = *(unsigned short*) &pFormat[2]; + + NdrpAlignLength(&(pStubMsg->BufferLength), alignment); + NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size); + + pFormat += 4; + + if (*pFormat == FC_PSTRUCT) + NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + + printf("warning: NdrSimpleStructBufferSize unimplemented\n"); +} + +void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * member_layout<> + * FC_END + */ + + /** + * FC_CPSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * pointer_layout<> + * member_layout<> FC_END + */ + + printf("warning: NdrConformantStructBufferSize unimplemented\n"); +} + +void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_CVSTRUCT alignment<1> + * memory_size<2> + * offset_to_array_description<2> + * [pointer_layout<>] + * layout<> + * FC_END + */ + + printf("warning: NdrConformantVaryingStructBufferSize unimplemented\n"); +} + +ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) +{ + ULONG size = 0; + + while (*pFormat != FC_END) + { + switch (*pFormat) + { + case FC_BYTE: + case FC_CHAR: + case FC_SMALL: + case FC_USMALL: + size += sizeof(BYTE); + break; + + case FC_WCHAR: + case FC_SHORT: + case FC_USHORT: + case FC_ENUM16: + size += sizeof(USHORT); + break; + + case FC_LONG: + case FC_ULONG: + case FC_ENUM32: + size += sizeof(ULONG); + break; + + case FC_INT3264: + case FC_UINT3264: + size += sizeof(INT_PTR); + break; + + case FC_FLOAT: + size += sizeof(FLOAT); + break; + + case FC_DOUBLE: + size += sizeof(DOUBLE); + break; + + case FC_HYPER: + size += sizeof(ULONGLONG); + break; + + case FC_ERROR_STATUS_T: + size += sizeof(error_status_t); + break; + + case FC_IGNORE: + break; + + case FC_RP: + case FC_UP: + case FC_OP: + case FC_FP: + case FC_POINTER: + size += sizeof(void*); + if (*pFormat != FC_POINTER) + pFormat += 4; + break; + + case FC_ALIGNM2: + NdrpAlignLength(&size, 2); + break; + + case FC_ALIGNM4: + NdrpAlignLength(&size, 4); + break; + + case FC_ALIGNM8: + NdrpAlignLength(&size, 8); + break; + + case FC_STRUCTPAD1: + case FC_STRUCTPAD2: + case FC_STRUCTPAD3: + case FC_STRUCTPAD4: + case FC_STRUCTPAD5: + case FC_STRUCTPAD6: + case FC_STRUCTPAD7: + size += *pFormat - FC_STRUCTPAD1 + 1; + break; + + case FC_PAD: + break; + + case FC_EMBEDDED_COMPLEX: + printf("warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented\n"); + break; + + default: + printf("warning: NdrComplexStructMemberSize 0x%02X unimplemented\n", *pFormat); + break; + } + + pFormat++; + } + + return size; +} + +void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + /** + * FC_BOGUS_STRUCT + * alignment<1> + * memory_size<2> + * offset_to_conformant_array_description<2> + * offset_to_pointer_layout<2> + * member_layout<> + * FC_END + * [pointer_layout<>] + */ + + ULONG_PTR MaxCount; + unsigned long Offset; + unsigned long ActualCount; + unsigned char* pMemoryCopy; + + unsigned char type; + unsigned char alignment; + unsigned short memory_size; + unsigned char* pointer_layout; + unsigned char* conformant_array_description; + unsigned short offset_to_pointer_layout; + unsigned short offset_to_conformant_array_description; + + type = pFormat[0]; + pMemoryCopy = pMemory; + pointer_layout = conformant_array_description = NULL; + + if (type != FC_BOGUS_STRUCT) + { + printf("error: expected FC_BOGUS_STRUCT, got 0x%02X\n", type); + return; + } + + alignment = pFormat[1] + 1; + memory_size = *(unsigned short*) &pFormat[2]; + + NdrpAlignLength(&(pStubMsg->BufferLength), alignment); + + if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) + { + unsigned long BufferLengthCopy = pStubMsg->BufferLength; + int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers; + + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy; + + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = BufferLengthCopy; + } + + pFormat += 4; + + offset_to_conformant_array_description = *(unsigned short*) &pFormat[0]; + + if (offset_to_conformant_array_description) + conformant_array_description = (unsigned char*) pFormat + offset_to_conformant_array_description; + pFormat += 2; + + offset_to_pointer_layout = *(unsigned short*) &pFormat[0]; + + if (offset_to_pointer_layout) + pointer_layout = (unsigned char*) pFormat + offset_to_pointer_layout; + pFormat += 2; + + pStubMsg->Memory = pMemory; + + if (conformant_array_description) + { + ULONG size; + unsigned char array_type; + + array_type = conformant_array_description[0]; + size = NdrComplexStructMemberSize(pStubMsg, pFormat); + + printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); + + NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description); + NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description); + + MaxCount = pStubMsg->MaxCount; + ActualCount = pStubMsg->ActualCount; + Offset = pStubMsg->Offset; + } + + if (conformant_array_description) + { + unsigned char array_type; + + array_type = conformant_array_description[0]; + + pStubMsg->MaxCount = MaxCount; + pStubMsg->ActualCount = ActualCount; + pStubMsg->Offset = Offset; + + printf("warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented\n", array_type); + } + + pStubMsg->Memory = pMemoryCopy; + + if (pStubMsg->PointerLength > 0) + { + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + } +} diff --git a/libwinpr-rpc/ndr_structure.h b/libwinpr-rpc/ndr_structure.h new file mode 100644 index 000000000..ca60c62fe --- /dev/null +++ b/libwinpr-rpc/ndr_structure.h @@ -0,0 +1,30 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_STRUCTURE_H +#define WINPR_RPC_NDR_STRUCTURE_H + +#include + +void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_STRUCTURE_H */ diff --git a/libwinpr-rpc/ndr_union.c b/libwinpr-rpc/ndr_union.c new file mode 100644 index 000000000..644ef5831 --- /dev/null +++ b/libwinpr-rpc/ndr_union.c @@ -0,0 +1,35 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "ndr_union.h" + +void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrEncapsulatedUnionBufferSize unimplemented\n"); +} + +void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + printf("warning: NdrNonEncapsulatedUnionBufferSize unimplemented\n"); +} diff --git a/libwinpr-rpc/ndr_union.h b/libwinpr-rpc/ndr_union.h new file mode 100644 index 000000000..7cd81d05b --- /dev/null +++ b/libwinpr-rpc/ndr_union.h @@ -0,0 +1,28 @@ +/** + * WinPR: Windows Portable Runtime + * Microsoft Remote Procedure Call (MSRPC) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_RPC_NDR_UNION_H +#define WINPR_RPC_NDR_UNION_H + +#include + +void NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); +void NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + +#endif /* WINPR_RPC_NDR_UNION_H */ From 24eb2f46fec7a432ffab672423ec3618ad800394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 5 May 2012 18:42:35 -0400 Subject: [PATCH 46/47] libwinpr-rpc: fix compilation on Linux --- include/winpr/ndr.h | 2 +- include/winpr/rpc.h | 4 ++-- include/winpr/sspi.h | 2 +- include/winpr/wtypes.h | 2 +- libfreerdp-core/rpc.c | 4 ++++ libwinpr-rpc/ndr.c | 2 ++ libwinpr-rpc/ndr_pointer.h | 7 +++++++ libwinpr-rpc/ndr_structure.c | 4 ++-- libwinpr-rpc/rpc.c | 2 +- 9 files changed, 21 insertions(+), 8 deletions(-) diff --git a/include/winpr/ndr.h b/include/winpr/ndr.h index e6a8ab79e..85a357645 100644 --- a/include/winpr/ndr.h +++ b/include/winpr/ndr.h @@ -525,6 +525,6 @@ typedef void (*NDR_TYPE_MARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned typedef void (*NDR_TYPE_UNMARSHALL_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, unsigned char FormatChar); typedef void (*NDR_TYPE_FREE_ROUTINE)(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); -WINPR_API CLIENT_CALL_RETURN RPC_VAR_ENTRY NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); +WINPR_API CLIENT_CALL_RETURN NdrClientCall2(PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...); #endif /* WINPR_RPC_NDR_H */ diff --git a/include/winpr/rpc.h b/include/winpr/rpc.h index 8be422f51..31257d2ce 100644 --- a/include/winpr/rpc.h +++ b/include/winpr/rpc.h @@ -37,9 +37,9 @@ typedef PCONTEXT_HANDLE PTUNNEL_CONTEXT_HANDLE_SERIALIZE; typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE; typedef PCONTEXT_HANDLE PCHANNEL_CONTEXT_HANDLE_SERIALIZE; -void RpcRaiseException(RPC_STATUS exception); - #include #include +void RpcRaiseException(RPC_STATUS exception); + #endif /* WINPR_RPC_H */ diff --git a/include/winpr/sspi.h b/include/winpr/sspi.h index 376d08f16..5be7642b3 100644 --- a/include/winpr/sspi.h +++ b/include/winpr/sspi.h @@ -43,7 +43,7 @@ #else #define FREERDP_SSPI -#include +#include #endif diff --git a/include/winpr/wtypes.h b/include/winpr/wtypes.h index c01e2d4df..3df5897b9 100644 --- a/include/winpr/wtypes.h +++ b/include/winpr/wtypes.h @@ -113,7 +113,7 @@ typedef struct _GUID unsigned long Data1; unsigned short Data2; unsigned short Data3; - byte Data4[8]; + BYTE Data4[8]; } GUID, UUID, *PGUID; #ifdef UNICODE diff --git a/libfreerdp-core/rpc.c b/libfreerdp-core/rpc.c index a8d0c98b0..805529002 100644 --- a/libfreerdp-core/rpc.c +++ b/libfreerdp-core/rpc.c @@ -189,6 +189,10 @@ STREAM* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_le http_context = rpc->ntlm_http_out->context; http_request_set_method(http_request, "RPC_OUT_DATA"); } + else + { + return NULL; + } http_request->ContentLength = content_length; http_request_set_uri(http_request, http_context->URI); diff --git a/libwinpr-rpc/ndr.c b/libwinpr-rpc/ndr.c index ccba296e3..bca80d84a 100644 --- a/libwinpr-rpc/ndr.c +++ b/libwinpr-rpc/ndr.c @@ -18,6 +18,8 @@ */ #include +#include +#include #include diff --git a/libwinpr-rpc/ndr_pointer.h b/libwinpr-rpc/ndr_pointer.h index 3712316af..676832239 100644 --- a/libwinpr-rpc/ndr_pointer.h +++ b/libwinpr-rpc/ndr_pointer.h @@ -24,6 +24,13 @@ PFORMAT_STRING NdrpSkipPointerLayout(PFORMAT_STRING pFormat); +void NdrpPointerBufferSize(unsigned char* pMemory, PFORMAT_STRING pFormat, PMIDL_STUB_MESSAGE pStubMsg); + +PFORMAT_STRING NdrpEmbeddedRepeatPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char* pMemory, PFORMAT_STRING pFormat, unsigned char** ppMemory); + +PFORMAT_STRING NdrpEmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); + void NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); void NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat); diff --git a/libwinpr-rpc/ndr_structure.c b/libwinpr-rpc/ndr_structure.c index 849e71bd6..d7f3957c2 100644 --- a/libwinpr-rpc/ndr_structure.c +++ b/libwinpr-rpc/ndr_structure.c @@ -21,10 +21,10 @@ #include #include - +#include "ndr_private.h" +#include "ndr_pointer.h" #include "ndr_structure.h" - /* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */ void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) diff --git a/libwinpr-rpc/rpc.c b/libwinpr-rpc/rpc.c index 4200bb395..c76096627 100644 --- a/libwinpr-rpc/rpc.c +++ b/libwinpr-rpc/rpc.c @@ -23,5 +23,5 @@ void RpcRaiseException(RPC_STATUS exception) { - printf("RpcRaiseException: 0x%08X\n", exception); + printf("RpcRaiseException: 0x%08luX\n", exception); } From d317b62cd00bade519b623b9df45fb12e13c8f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 5 May 2012 18:51:23 -0400 Subject: [PATCH 47/47] libfreerdp-core: make MSRPC engine usage optional --- libfreerdp-core/tsg.c | 154 ++++++++++++++++++++++++++++++++---------- 1 file changed, 120 insertions(+), 34 deletions(-) diff --git a/libfreerdp-core/tsg.c b/libfreerdp-core/tsg.c index ffb7a7222..f340f2bac 100644 --- a/libfreerdp-core/tsg.c +++ b/libfreerdp-core/tsg.c @@ -1688,6 +1688,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], uint32 count, return length; } +#ifndef WITH_MSRPC boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) { uint8* data; @@ -1718,15 +1719,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ - { - TSG_PACKET tsgPacket; - PTSG_PACKET tsgPacketResponse; - PTUNNEL_CONTEXT_HANDLE_SERIALIZE tunnelContext; - unsigned long tunnelId; - - TsProxyCreateTunnel(&tsgPacket, &tsgPacketResponse, &tunnelContext, &tunnelId); - } - DEBUG_TSG("TsProxyCreateTunnel"); status = rpc_tsg_write(rpc, tsg_packet1, sizeof(tsg_packet1), 1); @@ -1767,14 +1759,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * */ - { - TSG_PACKET tsgPacket; - PTSG_PACKET tsgPacketResponse; - PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; - - TsProxyAuthorizeTunnel(&tunnelContext, &tsgPacket, &tsgPacketResponse); - } - DEBUG_TSG("TsProxyAuthorizeTunnel"); status = rpc_tsg_write(rpc, tsg_packet2, sizeof(tsg_packet2), 2); @@ -1805,14 +1789,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ - { - TSG_PACKET tsgPacket; - PTSG_PACKET tsgPacketResponse; - PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; - - TsProxyMakeTunnelCall(&tunnelContext, 0, &tsgPacket, &tsgPacketResponse); - } - DEBUG_TSG("TsProxyMakeTunnelCall"); status = rpc_tsg_write(rpc, tsg_packet3, sizeof(tsg_packet3), 3); @@ -1849,15 +1825,6 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) * ); */ - { - unsigned long channelId; - TSENDPOINTINFO tsEndPointInfo; - PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; - PCHANNEL_CONTEXT_HANDLE_SERIALIZE channelContext; - - TsProxyCreateChannel(&tunnelContext, &tsEndPointInfo, &channelContext, &channelId); - } - DEBUG_TSG("TsProxyCreateChannel"); status = rpc_tsg_write(rpc, s_p4->data, s_p4->size, 4); @@ -1905,6 +1872,125 @@ boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) return true; } +#else +boolean tsg_connect(rdpTsg* tsg, const char* hostname, uint16 port) +{ + uint8* data; + uint32 length; + STREAM* s_p4; + int status = -1; + UNICONV* tsg_uniconv; + rdpRpc* rpc = tsg->rpc; + uint8* dest_addr_unic; + uint32 dest_addr_unic_len; + + if (!rpc_connect(rpc)) + { + printf("rpc_connect failed!\n"); + return false; + } + + DEBUG_TSG("rpc_connect success"); + + /** + * 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"); + + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_SERIALIZE tunnelContext; + unsigned long tunnelId; + + TsProxyCreateTunnel(&tsgPacket, &tsgPacketResponse, &tunnelContext, &tunnelId); + } + + /** + * OpNum = 2 + * + * HRESULT TsProxyAuthorizeTunnel( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in, ref] PTSG_PACKET tsgPacket, + * [out, ref] PTSG_PACKET* tsgPacketResponse + * ); + * + */ + + DEBUG_TSG("TsProxyAuthorizeTunnel"); + + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + + TsProxyAuthorizeTunnel(&tunnelContext, &tsgPacket, &tsgPacketResponse); + } + + /** + * OpNum = 3 + * + * HRESULT TsProxyMakeTunnelCall( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in] unsigned long procId, + * [in, ref] PTSG_PACKET tsgPacket, + * [out, ref] PTSG_PACKET* tsgPacketResponse + * ); + */ + + DEBUG_TSG("TsProxyMakeTunnelCall"); + + { + TSG_PACKET tsgPacket; + PTSG_PACKET tsgPacketResponse; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + + TsProxyMakeTunnelCall(&tunnelContext, 0, &tsgPacket, &tsgPacketResponse); + } + + /** + * OpNum = 4 + * + * HRESULT TsProxyCreateChannel( + * [in] PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, + * [in, ref] PTSENDPOINTINFO tsEndPointInfo, + * [out] PCHANNEL_CONTEXT_HANDLE_SERIALIZE* channelContext, + * [out] unsigned long* channelId + * ); + */ + + DEBUG_TSG("TsProxyCreateChannel"); + + { + unsigned long channelId; + TSENDPOINTINFO tsEndPointInfo; + PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext; + PCHANNEL_CONTEXT_HANDLE_SERIALIZE channelContext; + + TsProxyCreateChannel(&tunnelContext, &tsEndPointInfo, &channelContext, &channelId); + } + + /** + * OpNum = 8 + * + * DWORD TsProxySetupReceivePipe( + * [in, max_is(32767)] byte pRpcMessage[] + * ); + */ + + DEBUG_TSG("TsProxySetupReceivePipe"); + + return true; +} +#endif int tsg_read(rdpTsg* tsg, uint8* data, uint32 length) {