From 6599e1f2a30eab16a93f3b503d122040c96aef32 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Tue, 14 May 2013 16:24:05 +0800 Subject: [PATCH 01/15] cmdline: add max-fast-path-size argument. --- client/common/cmdline.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 1055ea827..ea22d78fd 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -126,6 +126,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "glyph-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "glyph cache" }, { "codec-cache", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "bitmap codec cache" }, { "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" }, + { "max-fast-path-size", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "maximum fast-path update size" }, { "async-input", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous input" }, { "async-update", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous update" }, { "async-transport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous transport (unstable)" }, @@ -1554,6 +1555,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->FastPathInput = arg->Value ? TRUE : FALSE; settings->FastPathOutput = arg->Value ? TRUE : FALSE; } + CommandLineSwitchCase(arg, "max-fast-path-size") + { + settings->MultifragMaxRequestSize = atoi(arg->Value); + } CommandLineSwitchCase(arg, "async-input") { settings->AsyncInput = arg->Value ? TRUE : FALSE; From 8a1b59a127aa1da7c9f27bc1d256457453e6ea34 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Tue, 14 May 2013 16:24:43 +0800 Subject: [PATCH 02/15] libfreerdp-core/tcp: add a null pointer check. --- libfreerdp/core/tcp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index a9331106a..a0ad86406 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -120,6 +120,9 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port) UINT32 option_value; socklen_t option_len; + if (hostname == NULL) + return FALSE; + if (hostname[0] == '/') { tcp->sockfd = freerdp_uds_connect(hostname); From 7adab0f79c65cc898c63431084fcecb3f600752d Mon Sep 17 00:00:00 2001 From: Nigel Reeves Date: Wed, 15 May 2013 09:42:21 +0100 Subject: [PATCH 03/15] Prevent segfault when start a RAIL remote Application --- client/X11/xf_keyboard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index a7ff67ce0..e7db12cc6 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -195,12 +195,13 @@ void xf_kbd_focus_in(xfInfo* xfi) Window wdummy; UINT32 state = 0; - input = xfi->instance->input; - - syncFlags = xf_kbd_get_toggle_keys_state(xfi); - XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state); - - input->FocusInEvent(input, syncFlags, mouseX, mouseY); + if (xfi->display && xfi->window) + { + input = xfi->instance->input; + syncFlags = xf_kbd_get_toggle_keys_state(xfi); + XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state); + input->FocusInEvent(input, syncFlags, mouseX, mouseY); + } } BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym) From 25229f520f7d9cf6986cb93caecf50b5f36734af Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 19 May 2013 16:46:02 -0700 Subject: [PATCH 04/15] channels/server: provide error codes to distinguish between not-registered and not-ready state. --- channels/server/channels.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/channels/server/channels.c b/channels/server/channels.c index 18facafd5..eeae1dc22 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -552,9 +552,25 @@ void* WTSVirtualChannelOpenEx( if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) { + for (i = 0; i < client->settings->ChannelCount; i++) + { + if (client->settings->ChannelDefArray[i].joined && + strncmp(client->settings->ChannelDefArray[i].Name, "drdynvc", 7) == 0) + { + break; + } + } + if (i >= client->settings->ChannelCount) + { + DEBUG_DVC("Dynamic virtual channel not registered."); + SetLastError(ERROR_NOT_FOUND); + return NULL; + } + if (vcm->drdynvc_channel == NULL || vcm->drdynvc_state != DRDYNVC_STATE_READY) { DEBUG_DVC("Dynamic virtual channel not ready."); + SetLastError(ERROR_NOT_READY); return NULL; } @@ -586,7 +602,10 @@ void* WTSVirtualChannelOpenEx( len = strlen(pVirtualName); if (len > 8) + { + SetLastError(ERROR_NOT_FOUND); return NULL; + } for (i = 0; i < client->settings->ChannelCount; i++) { @@ -598,7 +617,10 @@ void* WTSVirtualChannelOpenEx( } if (i >= client->settings->ChannelCount) + { + SetLastError(ERROR_NOT_FOUND); return NULL; + } channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle; From 5aa49de0c06e3c210070f4d7c70d83b5e2030237 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 19 May 2013 21:57:08 -0700 Subject: [PATCH 05/15] include: add some missing extern C decl. --- include/freerdp/server/audin.h | 8 ++++++++ include/freerdp/server/rdpsnd.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/include/freerdp/server/audin.h b/include/freerdp/server/audin.h index 9eb5f4be9..885c1674c 100644 --- a/include/freerdp/server/audin.h +++ b/include/freerdp/server/audin.h @@ -90,7 +90,15 @@ struct _audin_server_context psAudinServerReceiveSamples ReceiveSamples; }; +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API audin_server_context* audin_server_context_new(WTSVirtualChannelManager* vcm); FREERDP_API void audin_server_context_free(audin_server_context* context); +#ifdef __cplusplus +} +#endif + #endif /* FREERDP_CHANNEL_AUDIN_SERVER_H */ diff --git a/include/freerdp/server/rdpsnd.h b/include/freerdp/server/rdpsnd.h index 6349874fe..8b0c163c2 100644 --- a/include/freerdp/server/rdpsnd.h +++ b/include/freerdp/server/rdpsnd.h @@ -91,7 +91,15 @@ struct _rdpsnd_server_context psRdpsndServerActivated Activated; }; +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API rdpsnd_server_context* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm); FREERDP_API void rdpsnd_server_context_free(rdpsnd_server_context* context); +#ifdef __cplusplus +} +#endif + #endif /* FREERDP_CHANNEL_RDPSND_SERVER_H */ From 583938dcb819413775d42b4988c803a49fe48ff7 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Tue, 21 May 2013 15:42:49 +0200 Subject: [PATCH 06/15] iOS: Fixed password storage on higher iOS versions --- client/iOS/Models/Encryptor.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/iOS/Models/Encryptor.m b/client/iOS/Models/Encryptor.m index 112572218..f4f6ad2f0 100644 --- a/client/iOS/Models/Encryptor.m +++ b/client/iOS/Models/Encryptor.m @@ -44,8 +44,7 @@ if (CCKeyDerivationPBKDF != NULL) { - int rounds = CCCalibratePBKDF(kCCPBKDF2, strlen(plaintext_password_data), TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, TSXEncryptorPBKDF2KeySize, 100); - int ret = CCKeyDerivationPBKDF(kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data)-1, (const uint8_t*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, rounds, derived_key, TSXEncryptorPBKDF2KeySize); + int ret = CCKeyDerivationPBKDF(kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data)-1, (const uint8_t*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, TSXEncryptorPBKDF2Rounds, derived_key, TSXEncryptorPBKDF2KeySize); //NSLog(@"CCKeyDerivationPBKDF ret = %d; key: %@", ret, [NSData dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]); if (ret) From 9e59fc905dfe5365a7192b566d6a8b9ef4b54271 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Fri, 17 May 2013 13:11:10 +0200 Subject: [PATCH 07/15] client: print detected path to known_host file Use detected path instead of hard coded for error messages --- include/freerdp/crypto/tls.h | 2 +- libfreerdp/crypto/tls.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index 258ee2ebb..c396679b3 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -62,7 +62,7 @@ FREERDP_API int tls_wait_read(rdpTls* tls); FREERDP_API int tls_wait_write(rdpTls* tls); FREERDP_API BOOL 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_error(char* hostname, char* fingerprint, char* hosts_file); FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count); FREERDP_API BOOL tls_print_error(char* func, SSL* connection, int value); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index e195031d9..e5d3f3ca4 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -603,7 +603,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) else if (match == -1) { /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ - tls_print_certificate_error(hostname, fingerprint); + tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file); if (instance->VerifyChangedCertificate) accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, ""); @@ -644,7 +644,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) return verification_status; } -void tls_print_certificate_error(char* hostname, char* fingerprint) +void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file) { fprintf(stderr, "The host key for %s has changed\n", hostname); fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); @@ -655,7 +655,7 @@ void tls_print_certificate_error(char* hostname, char* fingerprint) fprintf(stderr, "It is also possible that a host key has just been changed.\n"); fprintf(stderr, "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint); fprintf(stderr, "Please contact your system administrator.\n"); - fprintf(stderr, "Add correct host key in ~/.freerdp/known_hosts to get rid of this message.\n"); + fprintf(stderr, "Add correct host key in %s to get rid of this message.\n", hosts_file); fprintf(stderr, "Host key for %s has changed and you have requested strict checking.\n", hostname); fprintf(stderr, "Host key verification failed.\n"); } From a6cfa931b50fe0cca886d67cd4ee77b4eb3355c4 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 21 May 2013 12:36:44 +0200 Subject: [PATCH 08/15] core: changed type of FrameAcknowledge --- include/freerdp/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 035c9c7f1..7e8e42498 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1177,7 +1177,7 @@ struct rdp_settings /* NSCodec */ ALIGN64 BOOL NSCodec; /* 3712 */ ALIGN64 UINT32 NSCodecId; /* 3713 */ - ALIGN64 BOOL FrameAcknowledge; /* 3714 */ + ALIGN64 UINT32 FrameAcknowledge; /* 3714 */ UINT64 padding3776[3776 - 3715]; /* 3715 */ /* JPEG */ From a0fc0513e5bb0ee4685a2d0f113a38551e0c074b Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 21 May 2013 15:15:49 +0200 Subject: [PATCH 09/15] core: properly set MultifragMaxRequestSize for rfx The RemoteFX spec states that the MultifragMaxRequestSize must be at least as big as the one received by the server. If MultifragMaxRequestSize is too small the server disables RemoteFX (Codec). --- libfreerdp/core/capabilities.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 8080f9e2e..f297a1232 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -2196,6 +2196,8 @@ BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdp return FALSE; Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ + if (settings->RemoteFxCodec && settings->MultifragMaxRequestSize < multifragMaxRequestSize) + settings->MultifragMaxRequestSize = multifragMaxRequestSize; return TRUE; } From 0dc22d5a30a1c7d146b2a835b2032668127c33e9 Mon Sep 17 00:00:00 2001 From: Simon Engledew Date: Tue, 21 May 2013 16:06:00 +0100 Subject: [PATCH 10/15] Fixed a range of BER boundary encoding bugs which would occur when any NLA packet hit the 127 character mark. Removed ber#get_content_length as it was not behaving deterministically. --- include/freerdp/crypto/ber.h | 17 ++-- libfreerdp/core/nla.c | 165 +++++++++++++++++------------------ libfreerdp/crypto/ber.c | 118 +++++++++++++------------ 3 files changed, 148 insertions(+), 152 deletions(-) diff --git a/include/freerdp/crypto/ber.h b/include/freerdp/crypto/ber.h index 2f04c87e3..59e1cceea 100644 --- a/include/freerdp/crypto/ber.h +++ b/include/freerdp/crypto/ber.h @@ -54,10 +54,9 @@ FREERDP_API BOOL ber_read_length(wStream* s, int* length); FREERDP_API int ber_write_length(wStream* s, int length); -FREERDP_API int _ber_skip_length(int length); -FREERDP_API int ber_get_content_length(int length); +FREERDP_API int _ber_sizeof_length(int length); FREERDP_API BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc); -FREERDP_API void ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc); +FREERDP_API int ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc); FREERDP_API BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length); FREERDP_API void ber_write_application_tag(wStream* s, BYTE tag, int length); FREERDP_API BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length); @@ -65,21 +64,21 @@ FREERDP_API BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count); FREERDP_API void ber_write_enumerated(wStream* s, BYTE enumerated, BYTE count); FREERDP_API BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc); FREERDP_API int ber_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc); -FREERDP_API int ber_skip_contextual_tag(int length); +FREERDP_API int ber_sizeof_contextual_tag(int length); FREERDP_API BOOL ber_read_sequence_tag(wStream* s, int* length); FREERDP_API int ber_write_sequence_tag(wStream* s, int length); -FREERDP_API int ber_skip_sequence(int length); -FREERDP_API int ber_skip_sequence_tag(int length); +FREERDP_API int ber_sizeof_sequence(int length); +FREERDP_API int ber_sizeof_sequence_tag(int length); FREERDP_API BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding); -FREERDP_API void ber_write_octet_string(wStream* s, const BYTE* oct_str, int length); +FREERDP_API int ber_write_octet_string(wStream* s, const BYTE* oct_str, int length); FREERDP_API BOOL ber_read_octet_string_tag(wStream* s, int* length); FREERDP_API int ber_write_octet_string_tag(wStream* s, int length); -FREERDP_API int ber_skip_octet_string(int length); +FREERDP_API int ber_sizeof_octet_string(int length); FREERDP_API BOOL ber_read_BOOL(wStream* s, BOOL* value); FREERDP_API void ber_write_BOOL(wStream* s, BOOL value); FREERDP_API BOOL ber_read_integer(wStream* s, UINT32* value); FREERDP_API int ber_write_integer(wStream* s, UINT32 value); FREERDP_API BOOL ber_read_integer_length(wStream* s, int* length); -FREERDP_API int ber_skip_integer(UINT32 value); +FREERDP_API int ber_sizeof_integer(UINT32 value); #endif /* FREERDP_CRYPTO_BER_H */ diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 1d7de7288..e133b55f1 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -101,6 +101,9 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp); SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp); SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp); +#define ber_sizeof_sequence_octet_string(length) ber_sizeof_contextual_tag(ber_sizeof_octet_string(length)) + ber_sizeof_octet_string(length) +#define ber_write_sequence_octet_string(stream, context, value, length) ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), TRUE) + ber_write_octet_string(stream, value, length) + /** * Initialize NTLMSSP authentication module (client). * @param credssp @@ -112,7 +115,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) int length; freerdp* instance; rdpSettings* settings; - + settings = credssp->settings; instance = (freerdp*) settings->instance; @@ -238,7 +241,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) ZeroMemory(&output_buffer, sizeof(SecBuffer)); ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* + /* * from tspkg.dll: 0x00000132 * ISC_REQ_MUTUAL_AUTH * ISC_REQ_CONFIDENTIALITY @@ -456,7 +459,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) ZeroMemory(&output_buffer_desc, sizeof(SecBufferDesc)); ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* + /* * from tspkg.dll: 0x00000112 * ASC_REQ_MUTUAL_AUTH * ASC_REQ_CONFIDENTIALITY @@ -783,24 +786,24 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) return SEC_E_OK; } -int credssp_skip_ts_password_creds(rdpCredssp* credssp) +int credssp_sizeof_ts_password_creds(rdpCredssp* credssp) { int length; int ts_password_creds_length = 0; - length = ber_skip_octet_string(credssp->identity.DomainLength * 2); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(credssp->identity.DomainLength * 2); + length += ber_sizeof_contextual_tag(length); ts_password_creds_length += length; - length = ber_skip_octet_string(credssp->identity.UserLength * 2); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(credssp->identity.UserLength * 2); + length += ber_sizeof_contextual_tag(length); ts_password_creds_length += length; - length = ber_skip_octet_string(credssp->identity.PasswordLength * 2); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(credssp->identity.PasswordLength * 2); + length += ber_sizeof_contextual_tag(length); ts_password_creds_length += length; - length = ber_skip_sequence(ts_password_creds_length); + length = ber_sizeof_sequence(ts_password_creds_length); return length; } @@ -842,47 +845,41 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s) credssp->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; } -void credssp_write_ts_password_creds(rdpCredssp* credssp, wStream* s) +int credssp_write_ts_password_creds(rdpCredssp* credssp, wStream* s) { - int length; + int size = 0; + int innerSize = credssp_sizeof_ts_password_creds(credssp); - length = credssp_skip_ts_password_creds(credssp); + if (innerSize > Stream_GetRemainingLength(s)) + { + printf("\033[91m[ ERROR ] Not enough space allocated for ts_password_creds\033[0m"); + } /* TSPasswordCreds (SEQUENCE) */ - length = ber_get_content_length(length); - ber_write_sequence_tag(s, length); + + size += ber_write_sequence_tag(s, innerSize); /* [0] domainName (OCTET STRING) */ - ber_write_contextual_tag(s, 0, credssp->identity.DomainLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2); + size += ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2); /* [1] userName (OCTET STRING) */ - ber_write_contextual_tag(s, 1, credssp->identity.UserLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2); + size += ber_write_sequence_octet_string(s, 1, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2); /* [2] password (OCTET STRING) */ - ber_write_contextual_tag(s, 2, credssp->identity.PasswordLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2); + size += ber_write_sequence_octet_string(s, 2, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2); + + return size; } -int credssp_skip_ts_credentials(rdpCredssp* credssp) +int credssp_sizeof_ts_credentials(rdpCredssp* credssp) { - int length; - int ts_password_creds_length; - int ts_credentials_length = 0; + int size = 0; - length = ber_skip_integer(0); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; + size += ber_sizeof_integer(1); + size += ber_sizeof_contextual_tag(ber_sizeof_integer(1)); + size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp))); - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); - length = ber_skip_octet_string(ts_password_creds_length); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; - - length = ber_skip_sequence(ts_credentials_length); - - return length; + return size; } void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) @@ -909,28 +906,27 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) Stream_Free(s, FALSE); } -void credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) +int credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) { - int length; - int ts_password_creds_length; - - length = credssp_skip_ts_credentials(credssp); - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); + int size = 0; + int innerSize = credssp_sizeof_ts_credentials(credssp); /* TSCredentials (SEQUENCE) */ - length = ber_get_content_length(length); - length -= ber_write_sequence_tag(s, length); + size += ber_write_sequence_tag(s, innerSize); /* [0] credType (INTEGER) */ - length -= ber_write_contextual_tag(s, 0, 3, TRUE); - length -= ber_write_integer(s, 1); + size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE); + size += ber_write_integer(s, 1); /* [1] credentials (OCTET STRING) */ - length -= 1; - length -= ber_write_contextual_tag(s, 1, length, TRUE); - length -= ber_write_octet_string_tag(s, ts_password_creds_length); - credssp_write_ts_password_creds(credssp, s); + int passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)); + + size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE); + size += ber_write_octet_string_tag(s, passwordSize); + size += credssp_write_ts_password_creds(credssp, s); + + return size; } /** @@ -943,7 +939,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) wStream* s; int length; - length = credssp_skip_ts_credentials(credssp); + length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp)); sspi_SecBufferAlloc(&credssp->ts_credentials, length); s = Stream_New(credssp->ts_credentials.pvBuffer, length); @@ -1029,41 +1025,40 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) return SEC_E_OK; } -int credssp_skip_nego_token(int length) +int credssp_sizeof_nego_token(int length) { - length = der_skip_octet_string(length); - length += der_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_nego_tokens(int length) +int credssp_sizeof_nego_tokens(int length) { - length = credssp_skip_nego_token(length); - length += der_skip_sequence_tag(length); - length += der_skip_sequence_tag(length); - length += der_skip_contextual_tag(length); + length = credssp_sizeof_nego_token(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_pub_key_auth(int length) +int credssp_sizeof_pub_key_auth(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_auth_info(int length) +int credssp_sizeof_auth_info(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_ts_request(int length) +int credssp_sizeof_ts_request(int length) { - length += ber_skip_integer(2); - length += ber_skip_contextual_tag(3); - length += der_skip_sequence_tag(length); + length += ber_sizeof_integer(2); + length += ber_sizeof_contextual_tag(3); return length; } @@ -1081,18 +1076,18 @@ void credssp_send(rdpCredssp* credssp) int pub_key_auth_length; int auth_info_length; - nego_tokens_length = (credssp->negoToken.cbBuffer > 0) ? credssp_skip_nego_tokens(credssp->negoToken.cbBuffer) : 0; - pub_key_auth_length = (credssp->pubKeyAuth.cbBuffer > 0) ? credssp_skip_pub_key_auth(credssp->pubKeyAuth.cbBuffer) : 0; - auth_info_length = (credssp->authInfo.cbBuffer > 0) ? credssp_skip_auth_info(credssp->authInfo.cbBuffer) : 0; + nego_tokens_length = (credssp->negoToken.cbBuffer > 0) ? credssp_sizeof_nego_tokens(credssp->negoToken.cbBuffer) : 0; + pub_key_auth_length = (credssp->pubKeyAuth.cbBuffer > 0) ? credssp_sizeof_pub_key_auth(credssp->pubKeyAuth.cbBuffer) : 0; + auth_info_length = (credssp->authInfo.cbBuffer > 0) ? credssp_sizeof_auth_info(credssp->authInfo.cbBuffer) : 0; length = nego_tokens_length + pub_key_auth_length + auth_info_length; - ts_request_length = credssp_skip_ts_request(length); - s = Stream_New(NULL, ts_request_length); + ts_request_length = credssp_sizeof_ts_request(length); + + s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length)); /* TSRequest */ - length = der_get_content_length(ts_request_length); - der_write_sequence_tag(s, length); /* SEQUENCE */ + ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */ /* [0] version */ ber_write_contextual_tag(s, 0, 3, TRUE); @@ -1102,27 +1097,25 @@ void credssp_send(rdpCredssp* credssp) if (nego_tokens_length > 0) { length = nego_tokens_length; - length -= der_write_contextual_tag(s, 1, der_get_content_length(length), TRUE); /* NegoData */ - length -= der_write_sequence_tag(s, der_get_content_length(length)); /* SEQUENCE OF NegoDataItem */ - length -= der_write_sequence_tag(s, der_get_content_length(length)); /* NegoDataItem */ - length -= der_write_contextual_tag(s, 0, der_get_content_length(length), TRUE); /* [0] negoToken */ - der_write_octet_string(s, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */ + + length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))), TRUE); /* NegoData */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer)); /* NegoDataItem */ + length -= ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */ } /* [2] authInfo (OCTET STRING) */ if (auth_info_length > 0) { length = auth_info_length; - length -= ber_write_contextual_tag(s, 2, ber_get_content_length(length), TRUE); - ber_write_octet_string(s, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); + length -= ber_write_sequence_octet_string(s, 2, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); } /* [3] pubKeyAuth (OCTET STRING) */ if (pub_key_auth_length > 0) { length = pub_key_auth_length; - length -= ber_write_contextual_tag(s, 3, ber_get_content_length(length), TRUE); - ber_write_octet_string(s, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); + length -= ber_write_sequence_octet_string(s, 3, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); } transport_write(credssp->transport, s); diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index 3809f6dfc..2e8748a6e 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -30,7 +30,7 @@ BOOL ber_read_length(wStream* s, int* length) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -38,7 +38,7 @@ BOOL ber_read_length(wStream* s, int* length) { byte &= ~(0x80); - if(Stream_GetRemainingLength(s) < byte) + if (Stream_GetRemainingLength(s) < byte) return FALSE; if (byte == 1) @@ -63,33 +63,29 @@ BOOL ber_read_length(wStream* s, int* length) int ber_write_length(wStream* s, int length) { - if (length > 0x7F) + if (length > 0xFF) { - Stream_Write_UINT8(s, 0x82); + Stream_Write_UINT8(s, 0x80 ^ 2); Stream_Write_UINT16_BE(s, length); return 3; } - else + if (length > 0x7F) { + Stream_Write_UINT8(s, 0x80 ^ 1); Stream_Write_UINT8(s, length); - return 1; + return 2; } + Stream_Write_UINT8(s, length); + return 1; } -int _ber_skip_length(int length) +int _ber_sizeof_length(int length) { - if (length > 0x80) + if (length > 0xFF) return 3; - else - return 1; -} - -int ber_get_content_length(int length) -{ - if (length > 0x81) - return length - 4; - else - return length - 2; + if (length > 0x7F) + return 2; + return 1; } /** @@ -103,7 +99,7 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -120,9 +116,10 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) * @param pc primitive (FALSE) or constructed (TRUE) */ -void ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) +int ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); + return 1; } /** @@ -138,14 +135,14 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) if (tag > 30) { - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) return FALSE; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -156,7 +153,7 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) } else { - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -195,7 +192,7 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -211,19 +208,19 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) int ber_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc) { Stream_Write_UINT8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_contextual_tag(int length) +int ber_sizeof_contextual_tag(int length) { - return _ber_skip_length(length) + 1; + return 1 + _ber_sizeof_length(length); } BOOL ber_read_sequence_tag(wStream* s, int* length) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -242,24 +239,24 @@ BOOL ber_read_sequence_tag(wStream* s, int* length) int ber_write_sequence_tag(wStream* s, int length) { Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_sequence(int length) +int ber_sizeof_sequence(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } -int ber_skip_sequence_tag(int length) +int ber_sizeof_sequence_tag(int length) { - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { int length; - if(!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || + if (!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || !ber_read_length(s, &length)) return FALSE; @@ -284,11 +281,11 @@ void ber_write_enumerated(wStream* s, BYTE enumerated, BYTE count) BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) { - if(!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || + if (!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || !ber_read_length(s, length)) return FALSE; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, *padding); return TRUE; @@ -301,11 +298,14 @@ BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) * @param length string length */ -void ber_write_octet_string(wStream* s, const BYTE* oct_str, int length) +int ber_write_octet_string(wStream* s, const BYTE* oct_str, int length) { - ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); - ber_write_length(s, length); + int size = 0; + size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); + size += ber_write_length(s, length); Stream_Write(s, oct_str, length); + size += length; + return size; } BOOL ber_read_octet_string_tag(wStream* s, int* length) @@ -319,12 +319,12 @@ int ber_write_octet_string_tag(wStream* s, int length) { ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); ber_write_length(s, length); - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } -int ber_skip_octet_string(int length) +int ber_sizeof_octet_string(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } /** @@ -421,48 +421,52 @@ int ber_write_integer(wStream* s, UINT32 value) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); - if (value <= 0xFF) + if (value < 0x80) { ber_write_length(s, 1); Stream_Write_UINT8(s, value); - return 2; + return 3; } - else if (value < 0xFF80) + else if (value < 0x8000) { ber_write_length(s, 2); Stream_Write_UINT16_BE(s, value); - return 3; + return 4; } - else if (value < 0xFF8000) + else if (value < 0x800000) { ber_write_length(s, 3); Stream_Write_UINT8(s, (value >> 16)); Stream_Write_UINT16_BE(s, (value & 0xFFFF)); - return 4; + return 5; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x80000000) { ber_write_length(s, 4); Stream_Write_UINT32_BE(s, value); - return 5; + return 6; } return 0; } -int ber_skip_integer(UINT32 value) +int ber_sizeof_integer(UINT32 value) { - if (value <= 0xFF) + if (value < 0x80) { - return _ber_skip_length(1) + 2; + return 3; } - else if (value <= 0xFFFF) + else if (value < 0x8000) { - return _ber_skip_length(2) + 3; + return 4; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x800000) { - return _ber_skip_length(4) + 5; + return 5; + } + else if (value < 0x80000000) + { + return 6; } return 0; From f2aea91ccfc547ab5e589b2fe8d40ef556fb60d3 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Wed, 22 May 2013 01:48:43 -0700 Subject: [PATCH 11/15] Android/iOS: Fixes for using RemoteFX with Bitmap Cache V3 --- .../Android/FreeRDPCore/jni/android_freerdp.c | 21 ++++++++++++++----- client/iOS/Models/RDPSession.m | 9 +++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 51a6a4695..2d8ea7f8b 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -258,6 +258,8 @@ int android_freerdp_run(freerdp* instance) void* wfds[32]; fd_set rfds_set; fd_set wfds_set; + int select_status; + struct timeval timeout; memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); @@ -269,7 +271,7 @@ int android_freerdp_run(freerdp* instance) } ((androidContext*)instance->context)->is_connected = TRUE; - while (1) + while (!freerdp_shall_disconnect(instance)) { rcount = 0; wcount = 0; @@ -307,7 +309,14 @@ int android_freerdp_run(freerdp* instance) if (max_fds == 0) break; - if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); + + if (select_status == 0) + continue; + else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || @@ -495,9 +504,6 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE; settings->SoftwareGdi = TRUE; - - /* enable NSCodec */ - settings->NSCodec = TRUE; settings->BitmapCacheV3Enabled = TRUE; switch ((int) security) @@ -561,6 +567,11 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( settings->LargePointerFlag = TRUE; settings->FrameMarkerCommandEnabled = TRUE; } + else + { + /* enable NSCodec if we don't use remotefx */ + settings->NSCodec = TRUE; + } /* store performance settings */ if (disableWallpaper == JNI_TRUE) diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m index d43f27959..df924e29f 100644 --- a/client/iOS/Models/RDPSession.m +++ b/client/iOS/Models/RDPSession.m @@ -101,9 +101,12 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" settings->FrameMarkerCommandEnabled = TRUE; settings->FrameAcknowledge = 10; } - - // enable NSCodec - settings->NSCodec = TRUE; + else + { + // enable NSCodec if remotefx is not used + settings->NSCodec = TRUE; + } + settings->BitmapCacheV3Enabled = TRUE; // Performance flags From 120960fd4d85c642b96d98c46b814d74c9018f90 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Wed, 22 May 2013 10:58:11 +0200 Subject: [PATCH 12/15] libfreerdp-core: Added support for server initiated shutdown to TSG --- client/iOS/FreeRDP/ios_freerdp.m | 20 +++++++++++++++----- libfreerdp/core/gateway/rpc_client.c | 11 +++++++++++ libfreerdp/core/gateway/tsg.c | 10 ++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index ee0cdddc0..a5aeafd66 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -138,11 +138,13 @@ ios_run_freerdp(freerdp * instance) void* wfds[32]; fd_set rfds_set; fd_set wfds_set; + struct timeval timeout; + int select_status; memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); - while (1) + while (!freerdp_shall_disconnect(instance)) { rcount = wcount = 0; @@ -179,11 +181,19 @@ ios_run_freerdp(freerdp * instance) FD_SET(fds, &rfds_set); } - + if (max_fds == 0) break; - - if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); + + // timeout? + if (select_status == 0) + continue; + else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || @@ -191,7 +201,7 @@ ios_run_freerdp(freerdp * instance) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - NSLog(@"%s: max_sck is zero.", __func__); + NSLog(@"%s: select failed!", __func__); break; } } diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 3456b604c..458bfbe10 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -35,6 +35,8 @@ #include "rpc_client.h" +#include "../rdp.h" + wStream* rpc_client_fragment_pool_take(rdpRpc* rpc) { wStream* fragment = NULL; @@ -156,6 +158,15 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) if (StubLength == 4) { //fprintf(stderr, "Ignoring TsProxySendToServer Response\n"); + printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id); + + /* received a disconnect request from the server? */ + if (header->common.call_id == rpc->PipeCallId && header->common.pfc_flags & PFC_LAST_FRAG) + { + ((freerdp*)rpc->settings->instance)->context->rdp->disconnect = TRUE; + ((freerdp*)rpc->settings->instance)->context->rdp->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING; + } + rpc_client_fragment_pool_return(rpc, fragment); return 0; } diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 7d2b4a7fc..c6bb45dd1 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1371,8 +1371,14 @@ BOOL tsg_disconnect(rdpTsg* tsg) tsg->rpc->client->SynchronousReceive = TRUE; - if (!TsProxyCloseChannel(tsg, NULL)) - return FALSE; + /* if we are already in state pending (i.e. if a server initiated disconnect was issued) + we have to skip TsProxyCloseChannel - see Figure 13 in section 3.2.3 + */ + if (tsg->state != TSG_STATE_TUNNEL_CLOSE_PENDING) + { + if (!TsProxyCloseChannel(tsg, NULL)) + return FALSE; + } if (!TsProxyMakeTunnelCall(tsg, &tsg->TunnelContext, TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST, NULL, NULL)) return FALSE; From 0f0aadae94bfdbf54ebe20dfc257b7360a9acdb0 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Wed, 22 May 2013 05:18:37 -0700 Subject: [PATCH 13/15] Android: Added spanish and dutch translation stubs --- client/Android/aFreeRDP/res/values-es/strings.xml | 7 +++++++ client/Android/aFreeRDP/res/values-nl/strings.xml | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 client/Android/aFreeRDP/res/values-es/strings.xml create mode 100644 client/Android/aFreeRDP/res/values-nl/strings.xml diff --git a/client/Android/aFreeRDP/res/values-es/strings.xml b/client/Android/aFreeRDP/res/values-es/strings.xml new file mode 100644 index 000000000..f0aa7c6af --- /dev/null +++ b/client/Android/aFreeRDP/res/values-es/strings.xml @@ -0,0 +1,7 @@ + + + aFreeRDP + + aFreeRDP + Remote Computers + diff --git a/client/Android/aFreeRDP/res/values-nl/strings.xml b/client/Android/aFreeRDP/res/values-nl/strings.xml new file mode 100644 index 000000000..f0aa7c6af --- /dev/null +++ b/client/Android/aFreeRDP/res/values-nl/strings.xml @@ -0,0 +1,7 @@ + + + aFreeRDP + + aFreeRDP + Remote Computers + From fb9606ea77bcf9dcbfe6afab4407d8687a92cd26 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 23 May 2013 13:34:34 -0700 Subject: [PATCH 14/15] core/nla: fix non-standard C gramma. --- libfreerdp/core/nla.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index e133b55f1..d10bb89b3 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -910,6 +910,7 @@ int credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) { int size = 0; int innerSize = credssp_sizeof_ts_credentials(credssp); + int passwordSize; /* TSCredentials (SEQUENCE) */ size += ber_write_sequence_tag(s, innerSize); @@ -920,7 +921,7 @@ int credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) /* [1] credentials (OCTET STRING) */ - int passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)); + passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)); size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE); size += ber_write_octet_string_tag(s, passwordSize); From 06d06fdd2d45350f144ff3d79353e817b30811a7 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 23 May 2013 13:35:24 -0700 Subject: [PATCH 15/15] core/info: server missing audio info flags. --- libfreerdp/core/info.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index a792d2322..cf74d1dfa 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -240,6 +240,8 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings) Stream_Seek_UINT32(s); /* CodePage */ Stream_Read_UINT32(s, flags); /* flags */ + settings->AudioCapture = ((flags & RNS_INFO_AUDIOCAPTURE) ? TRUE : FALSE); + settings->AudioPlayback = ((flags & INFO_NOAUDIOPLAYBACK) ? FALSE : TRUE); settings->AutoLogonEnabled = ((flags & INFO_AUTOLOGON) ? TRUE : FALSE); settings->RemoteApplicationMode = ((flags & INFO_RAIL) ? TRUE : FALSE); settings->RemoteConsoleAudio = ((flags & INFO_REMOTECONSOLEAUDIO) ? TRUE : FALSE);