diff --git a/README b/README
index 6c67f0102..f40c20c56 100644
--- a/README
+++ b/README
@@ -8,10 +8,12 @@ interoperability can finally liberate your computing experience.
Resources
---------
-Website: http://www.freerdp.com/
-Wiki: https://github.com/FreeRDP/FreeRDP/wiki
+Project website: http://www.freerdp.com/
+Issue tracker: https://github.com/FreeRDP/FreeRDP/issues
Sources: https://github.com/FreeRDP/FreeRDP/
-API doc: http://www.freerdp.com/api/
+Wiki: https://github.com/FreeRDP/FreeRDP/wiki
+Downloads and other resources: http://pub.freerdp.com
+API doc: http://pub.freerdp.com/api/
IRC channel: #freerdp @ irc.freenode.net
Mailing list: https://lists.sourceforge.net/lists/listinfo/freerdp-devel
diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c
index 1147fa816..fb4d1db4a 100644
--- a/channels/rdpei/client/rdpei_main.c
+++ b/channels/rdpei/client/rdpei_main.c
@@ -118,7 +118,7 @@ int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId,
status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL);
#ifdef WITH_DEBUG_RDPEI
- printf("rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n",
+ fprintf(stderr, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status);
#endif
@@ -270,7 +270,7 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
if (protocolVersion != RDPINPUT_PROTOCOL_V1)
{
- printf("Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
+ fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
return -1;
}
@@ -296,7 +296,7 @@ int rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */
#ifdef WITH_DEBUG_RDPEI
- printf("rdpei_recv_pdu: eventId: %d (%s) length: %d\n",
+ fprintf(stderr, "rdpei_recv_pdu: eventId: %d (%s) length: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
#endif
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;
diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake
index 1632a7c18..161f5c061 100644
--- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake
+++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake
@@ -11,7 +11,7 @@
-
+
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/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml
index 5dfbf0c24..4bff58d5f 100644
--- a/client/Android/FreeRDPCore/res/values-nl/strings.xml
+++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml
@@ -105,6 +105,10 @@
3G Instellingen
3G Scherm
3G Prestatie
+ Gateway
+ Gateway inschakelen
+ Gateway instellingen
+ SDCard aankoppelen
Beveiliging
- Automatisch
diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake
index 751c235b9..3f481cb6a 100644
--- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake
+++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake
@@ -7,7 +7,7 @@
android:versionName="@GIT_REVISION@" >
-
+
+
+ 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
+
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)
diff --git a/client/common/cmdline.c b/client/common/cmdline.c
index 57bf9a74c..77353ff81 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)" },
@@ -1571,6 +1572,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;
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/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)
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
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/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/include/freerdp/error.h b/include/freerdp/error.h
index 27d54886a..8b0abd8f0 100644
--- a/include/freerdp/error.h
+++ b/include/freerdp/error.h
@@ -147,6 +147,7 @@ extern int connectErrorCode;
#define MCSCONNECTINITIALERROR ERRORSTART + 7
#define TLSCONNECTERROR ERRORSTART + 8
#define AUTHENTICATIONERROR ERRORSTART + 9
+#define INSUFFICIENTPRIVILEGESERROR ERRORSTART + 10
#ifdef __cplusplus
}
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 */
diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h
index 8bdf4ef9f..1b3d6ca90 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 */
diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c
index a5f3f7ee7..04df95e42 100644
--- a/libfreerdp/core/capabilities.c
+++ b/libfreerdp/core/capabilities.c
@@ -2242,6 +2242,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;
}
diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c
index 9b4643ccd..b28437ea5 100644
--- a/libfreerdp/core/freerdp.c
+++ b/libfreerdp/core/freerdp.c
@@ -109,12 +109,12 @@ BOOL freerdp_connect(freerdp* instance)
if (!status)
{
fprintf(stderr, "freerdp_post_connect failed\n");
-
+
if (!connectErrorCode)
{
connectErrorCode = POSTCONNECTERROR;
}
-
+
return FALSE;
}
@@ -153,6 +153,11 @@ BOOL freerdp_connect(freerdp* instance)
}
}
+ if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
+ {
+ connectErrorCode = INSUFFICIENTPRIVILEGESERROR;
+ }
+
if (!connectErrorCode)
{
connectErrorCode = UNDEFINEDCONNECTERROR;
diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c
index d07ff21d6..0c4908afa 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;
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index cee59322a..e8a04af9b 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);
diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c
index 8ab89ebd1..2b4b71992 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,13 @@ 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;
+ int length = 0;
- length = ber_skip_octet_string(credssp->identity.DomainLength * 2);
- length += ber_skip_contextual_tag(length);
- ts_password_creds_length += length;
-
- length = ber_skip_octet_string(credssp->identity.UserLength * 2);
- length += ber_skip_contextual_tag(length);
- ts_password_creds_length += length;
-
- length = ber_skip_octet_string(credssp->identity.PasswordLength * 2);
- length += ber_skip_contextual_tag(length);
- ts_password_creds_length += length;
-
- length = ber_skip_sequence(ts_password_creds_length);
+ length += ber_sizeof_sequence_octet_string(credssp->identity.DomainLength * 2);
+ length += ber_sizeof_sequence_octet_string(credssp->identity.UserLength * 2);
+ length += ber_sizeof_sequence_octet_string(credssp->identity.PasswordLength * 2);
return length;
}
@@ -842,47 +834,36 @@ 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;
-
- length = credssp_skip_ts_password_creds(credssp);
+ int size = 0;
+ int innerSize = credssp_sizeof_ts_password_creds(credssp);
/* 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 +890,28 @@ 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);
+ int passwordSize;
/* 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);
+ 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 +924,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 +1010,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 +1061,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 +1082,31 @@ 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 */
+
+ // assert length == 0
}
/* [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);
+
+ // assert length == 0
}
/* [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);
+
+ // assert length == 0
}
Stream_SealLength(s);
diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c
index 5e61a9f17..40e066747 100644
--- a/libfreerdp/core/peer.c
+++ b/libfreerdp/core/peer.c
@@ -138,6 +138,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s)
if(Stream_GetRemainingLength(s) < 4)
return FALSE;
Stream_Read_UINT32(s, client->ack_frame_id);
+ IFCALL(client->update->SurfaceFrameAcknowledge, client->update->context, client->ack_frame_id);
break;
case DATA_PDU_TYPE_REFRESH_RECT:
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);
diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c
index 3809f6dfc..38d98f411 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;
}
/**
@@ -419,50 +419,56 @@ BOOL ber_read_integer(wStream* s, UINT32* value)
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_universal_tag(s, BER_TAG_INTEGER, FALSE);
ber_write_length(s, 1);
Stream_Write_UINT8(s, value);
- return 2;
- }
- else if (value < 0xFF80)
- {
- ber_write_length(s, 2);
- Stream_Write_UINT16_BE(s, value);
return 3;
}
- else if (value < 0xFF8000)
+ else if (value < 0x8000)
{
+ ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE);
+ ber_write_length(s, 2);
+ Stream_Write_UINT16_BE(s, value);
+ return 4;
+ }
+ else if (value < 0x800000)
+ {
+ ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE);
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_universal_tag(s, BER_TAG_INTEGER, FALSE);
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;
diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c
index 483945f62..2ffa2bd84 100644
--- a/libfreerdp/crypto/crypto.c
+++ b/libfreerdp/crypto/crypto.c
@@ -430,6 +430,7 @@ char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths)
*lengths = NULL ;
return NULL;
}
+ GENERAL_NAMES_free(subject_alt_names);
return strings;
}
diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c
index 920f20488..78b9b637e 100644
--- a/libfreerdp/crypto/tls.c
+++ b/libfreerdp/crypto/tls.c
@@ -627,7 +627,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, "");
@@ -668,7 +668,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");
@@ -679,7 +679,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");
}
diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c
index 0d246f6ce..157b365b6 100644
--- a/winpr/libwinpr/utils/collections/ArrayList.c
+++ b/winpr/libwinpr/utils/collections/ArrayList.c
@@ -148,7 +148,9 @@ void ArrayList_Shift(wArrayList* arrayList, int index, int count)
}
else if (count < 0)
{
- MoveMemory(&arrayList->array[index], &arrayList->array[index - count], (arrayList->size + count) * sizeof(void*));
+ int chunk = arrayList->size - index + count;
+ if (chunk > 0)
+ MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void*));
arrayList->size += count;
}
}