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; } }