Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2014-05-21 11:17:58 -04:00
commit 4bac8374de
27 changed files with 576 additions and 119 deletions

1
.gitignore vendored
View File

@ -71,6 +71,7 @@ Release-*
*.vcxproj.*
*.vcproj
*.vcproj.*
*.aps
*.sdf
*.sln
*.suo

View File

@ -310,24 +310,34 @@ if(ANDROID)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG} -gdwarf-3")
endif()
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -llog")
if (NOT FREERDP_ANDROID_EXTERNAL_SSL_PATH)
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
set(FREERDP_ANDROID_EXTERNAL_SSL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
if (NOT FREERDP_EXTERNAL_JPEG_PATH)
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/jpeg8d")
set(FREERDP_EXTERNAL_JPEG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/jpeg8d")
else()
message(STATUS "FREERDP_ANDROID_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)")
message(STATUS "FREERDP_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)")
endif()
endif()
if (NOT FREERDP_EXTERNAL_SSL_PATH)
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
set(FREERDP_EXTERNAL_SSL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
else()
message(STATUS "FREERDP_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)")
endif()
if(WITH_GPROF)
if (NOT FREERDP_ANDROID_EXTERNAL_PROFILER_PATH)
if (NOT FREERDP_EXTERNAL_PROFILER_PATH)
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler")
set(FREERDP_ANDROID_EXTERNAL_PROFILER_PATH
set(FREERDP_EXTERNAL_PROFILER_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler")
else()
message(STATUS "FREERDP_ANDROID_EXTERNAL_PROFILER_PATH not set!")
message(STATUS "FREERDP_EXTERNAL_PROFILER_PATH not set!")
endif()
endif()
endif()
endif()
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_ANDROID_EXTERNAL_SSL_PATH})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_EXTERNAL_SSL_PATH} ${FREERDP_EXTERNAL_JPEG_PATH})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_EXTERNAL_PROFILER_PATH})
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/jni/${ANDROID_ABI})
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake
${CMAKE_BINARY_DIR}/scripts/regenerate_jni_headers.sh @ONLY)
@ -349,6 +359,12 @@ if(NOT WIN32)
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
endif()
if(WITH_VALGRIND_MEMCHECK)
check_include_files(valgrind/memcheck.h HAVE_VALGRIND_MEMCHECK_H)
else()
unset(HAVE_VALGRIND_MEMCHECK_H CACHE)
endif()
if(UNIX OR CYGWIN)
check_include_files(sys/eventfd.h HAVE_AIO_H)
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
@ -525,8 +541,8 @@ if(ANDROID)
if(WITH_GPROF)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg")
set(PROFILER_LIBRARIES
"${FREERDP_ANDROID_EXTERNAL_PROFILER_PATH}/obj/local/${ANDROID_ABI}/libandroid-ndk-profiler.a")
include_directories("${FREERDP_ANDROID_EXTERNAL_PROFILER_PATH}")
"${FREERDP_EXTERNAL_PROFILER_PATH}/obj/local/${ANDROID_ABI}/libandroid-ndk-profiler.a")
include_directories("${FREERDP_EXTERNAL_PROFILER_PATH}")
endif()
endif()

View File

@ -1,6 +1,6 @@
message("PRELOADING android cache")
set(CMAKE_TOOLCHAIN_FILE "cmake/AndroidToolchain.cmake" CACHE PATH "ToolChain file")
set(FREERDP_ANDROID_EXTERNAL_SSL_PATH $ENV{ANDROID_SSL_PATH} CACHE PATH "android ssl")
set(FREERDP_EXTERNAL_SSL_PATH $ENV{ANDROID_SSL_PATH} CACHE PATH "android ssl")
# ANDROID_NDK and ANDROID_SDK must be set as environment variable
#set(ANDROID_NDK $ENV{ANDROID_SDK} CACHE PATH "Android NDK")
#set(ANDROID_SDK "${ANDROID_NDK}" CACHE PATH "android SDK")

View File

@ -192,9 +192,6 @@ static int floatbar_paint(FloatBar* floatbar, HDC hdc)
{
int i;
if (!floatbar->wfc->fullscreen)
return -1;
/* paint background */
SelectObject(floatbar->hdcmem, floatbar->background);
StretchBlt(hdc, 0, 0, BACKGROUND_W, BACKGROUND_H, floatbar->hdcmem, 0, 0, BACKGROUND_W, BACKGROUND_H, SRCCOPY);
@ -421,12 +418,14 @@ static FloatBar* floatbar_create(wfContext* wfc)
int floatbar_hide(FloatBar* floatbar)
{
KillTimer(floatbar->hwnd, TIMER_HIDE);
MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->height, floatbar->width, floatbar->height, TRUE);
return 0;
}
int floatbar_show(FloatBar* floatbar)
{
SetTimer(floatbar->hwnd, TIMER_HIDE, 3000, NULL);
MoveWindow(floatbar->hwnd, floatbar->rect.left, floatbar->rect.top, floatbar->width, floatbar->height, TRUE);
return 0;
}

View File

@ -481,7 +481,7 @@ void wf_gdi_line_to(wfContext* wfc, LINE_TO_ORDER* line_to)
int x, y, w, h;
UINT32 pen_color;
pen_color = freerdp_color_convert_bgr(line_to->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
pen_color = freerdp_color_convert_var_bgr(line_to->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color);
@ -512,7 +512,7 @@ void wf_gdi_polyline(wfContext* wfc, POLYLINE_ORDER* polyline)
HPEN org_hpen;
UINT32 pen_color;
pen_color = freerdp_color_convert_bgr(polyline->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
pen_color = freerdp_color_convert_var_bgr(polyline->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
hpen = CreatePen(0, 1, pen_color);
org_rop2 = wf_set_rop2(wfc->drawing->hdc, polyline->bRop2);

View File

@ -65,6 +65,8 @@ int wf_create_console(void)
return 1;
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
fprintf(stderr, "Debug console created.\n");
return 0;
@ -619,6 +621,96 @@ static BOOL wf_auto_reconnect(freerdp* instance)
return FALSE;
}
void* wf_input_thread(void* arg)
{
int status;
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
assert( NULL != instance);
status = 1;
queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(instance,
FREERDP_INPUT_MESSAGE_QUEUE, &message);
if (!status)
break;
}
if (!status)
break;
}
ExitThread(0);
return NULL;
}
void* wf_update_thread(void* arg)
{
int status;
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
assert( NULL != instance);
status = 1;
queue = freerdp_get_message_queue(instance,
FREERDP_UPDATE_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(instance,
FREERDP_UPDATE_MESSAGE_QUEUE, &message);
if (!status)
break;
}
if (!status)
break;
}
ExitThread(0);
return NULL;
}
void* wf_channels_thread(void* arg)
{
int status;
HANDLE event;
rdpChannels* channels;
freerdp* instance = (freerdp*) arg;
assert(NULL != instance);
channels = instance->context->channels;
event = freerdp_channels_get_event_handle(instance);
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
status = freerdp_channels_process_pending_messages(instance);
if (!status)
break;
wf_process_channel_event(channels, instance);
}
ExitThread(0);
return NULL;
}
DWORD WINAPI wf_client_thread(LPVOID lpParam)
{
MSG msg;
@ -636,6 +728,15 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
wfContext* wfc;
freerdp* instance;
rdpChannels* channels;
rdpSettings* settings;
BOOL async_update;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
instance = (freerdp*) lpParam;
assert(NULL != instance);
@ -650,28 +751,59 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
return 0;
channels = instance->context->channels;
settings = instance->context->settings;
async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
if (async_update)
{
update_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) wf_update_thread,
instance, 0, NULL);
}
if (async_input)
{
input_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) wf_input_thread,
instance, 0, NULL);
}
if (async_channels)
{
channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) wf_channels_thread, instance, 0, NULL);
}
while (1)
{
rcount = 0;
wcount = 0;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_transport)
{
fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
break;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
break;
}
}
if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get wfreerdp file descriptor\n");
break;
}
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get channel manager file descriptor\n");
break;
}
if (!async_channels)
{
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get channel manager file descriptor\n");
break;
}
}
fds_count = 0;
/* setup read fds */
for (index = 0; index < rcount; index++)
@ -687,7 +819,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
if (fds_count == 0)
{
fprintf(stderr, "wfreerdp_run: fds_count is zero\n");
break;
//break;
}
/* do the wait */
@ -697,13 +829,16 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
break;
}
if (freerdp_check_fds(instance) != TRUE)
if (!async_transport)
{
if (wf_auto_reconnect(instance))
continue;
if (freerdp_check_fds(instance) != TRUE)
{
if (wf_auto_reconnect(instance))
continue;
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
break;
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
break;
}
}
if (freerdp_shall_disconnect(instance))
{
@ -714,12 +849,17 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
fprintf(stderr, "Failed to check wfreerdp file descriptor\n");
break;
}
if (freerdp_channels_check_fds(channels, instance) != TRUE)
if (!async_channels)
{
fprintf(stderr, "Failed to check channel manager file descriptor\n");
break;
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
fprintf(stderr, "Failed to check channel manager file descriptor\n");
break;
}
wf_process_channel_event(channels, instance);
}
wf_process_channel_event(channels, instance);
quit_msg = FALSE;
@ -766,6 +906,35 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
/* cleanup */
freerdp_channels_close(channels, instance);
if (async_update)
{
wMessageQueue* update_queue;
update_queue = freerdp_get_message_queue(instance,
FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(update_queue, 0);
WaitForSingleObject(update_thread, INFINITE);
CloseHandle(update_thread);
}
if (async_input)
{
wMessageQueue* input_queue;
input_queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_QUEUE);
MessageQueue_PostQuit(input_queue, 0);
WaitForSingleObject(input_thread, INFINITE);
CloseHandle(input_thread);
}
if (async_channels)
{
WaitForSingleObject(channels_thread, INFINITE);
CloseHandle(channels_thread);
}
freerdp_disconnect(instance);
printf("Main thread exited.\n");

Binary file not shown.

View File

@ -297,7 +297,6 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
if (count < 3)
return -1;
settings->RedirectDrives = TRUE;
settings->DeviceRedirection = TRUE;
drive = (RDPDR_DRIVE*) calloc(1, sizeof(RDPDR_DRIVE));
@ -1772,8 +1771,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
BYTE *base64;
int length;
crypto_base64_decode((BYTE *) (arg->Value),
(int) strlen(arg->Value), &base64, &length);
crypto_base64_decode((const char *) (arg->Value), (int) strlen(arg->Value),
&base64, &length);
if ((base64 != NULL) && (length == sizeof(ARC_SC_PRIVATE_PACKET)))
{
memcpy(settings->ServerAutoReconnectCookie, base64, length);

View File

@ -44,6 +44,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
endif()
if(NOT WIN32)
option(WITH_VALGRIND_MEMCHECK "Compile with valgrind helpers." OFF)
endif()
if(MSVC)
option(WITH_NATIVE_SSPI "Use native SSPI modules" ON)
option(WITH_WINMM "Use Windows Multimedia" ON)

View File

@ -25,6 +25,7 @@
#cmakedefine HAVE_TM_GMTOFF
#cmakedefine HAVE_AIO_H
#cmakedefine HAVE_PTHREAD_GNU_EXT
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
/* Options */

View File

@ -31,10 +31,12 @@ Multiple source versions and builds of static openssl libraries are floating aro
At the time of writing we have tested and used:
https://github.com/bmiklautz/Android-external-openssl-ndk-static
https://github.com/akallabeth/openssl-android
However, any other static build should work as well.
To build openssl:
For jpeg support https://github.com/akallabeth/jpeg8d has been tested and used.
However, any other static builds should work as well.
Build openssl and jpeg
======================
Set up ANDROID_NDK and ANDROID_SDK to the absolute paths on your machine.
From the project root folder run './scripts/android_setup_build_env.sh'
This will set up openssl and gprof helper libraries as required for FreeRDP.
@ -47,12 +49,13 @@ Integrated build
----------------
Run the following commands in the top level freerdp directory. Don't
forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_ANDROID_EXTERNAL_SSL_PATH
forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_EXTERNAL_SSL_PATH
to the absolut paths on your machine:
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
-DANDROID_NDK="_your_ndk_path_here_" \
-DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DFREERDP_EXTERNAL_JPEG_PATH="_your_jpeg_build_root_path_" \
-DANDROID_SDK="_your_sdk_path_here_" \
-DCMAKE_BUILD_TYPE=Debug
make
@ -62,12 +65,13 @@ After that you should have a client/Android/bin/aFreeRDP-debug.apk.
Manual ant builds
-----------------
First run cmake to prepare the build and build JNI.
Don't forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_ANDROID_EXTERNAL_SSL_PATH
Don't forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_EXTERNAL_SSL_PATH
to the absolut paths on your machine:
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
-DANDROID_NDK="_your_ndk_path_here_" \
-DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DFREERDP_EXTERNAL_JPEG_PATH="_your_jpeg_build_root_path_" \
-DANDROID_SDK="_your_sdk_path_here_" -DANDROID_BUILD_JAVA=OFF \
-DCMAKE_BUILD_TYPE=Debug
make
@ -85,7 +89,7 @@ the eclipse marketplace).
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
-DANDROID_NDK="_your_ndk_path_here_" \
-DFREERDP_ANDROID_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
-DCMAKE_BUILD_TYPE=Debug -DANDROID_BUILD_JAVA=OFF
make
@ -124,9 +128,12 @@ ANDROID_NDK (used from toolchain file)
ANDROID_ABI (used from toolchain file)
* Android ABI to build for (default is armeabi-v7a)
FREERDP_ANDROID_EXTERNAL_SSL_PATH (used by FindOpenSSL)
FREERDP_EXTERNAL_SSL_PATH (used by FindOpenSSL)
* absolut root path to the prebuild static openssl libraries
FREERDP_EXTERNAL_JPEG_PATH (used by FindJPEG)
* absolute root path to the prebuild static jpeg libraries
WITH_DEBUG_ANDROID_JNI
- enable debugging for JNI

View File

@ -144,6 +144,6 @@ FREERDP_API void crypto_reverse(BYTE* data, int length);
FREERDP_API void crypto_nonce(BYTE* nonce, int size);
FREERDP_API char* crypto_base64_encode(const BYTE* data, int length);
FREERDP_API void crypto_base64_decode(const BYTE* enc_data, int length, BYTE** dec_data, int* res_length);
FREERDP_API void crypto_base64_decode(const char* enc_data, int length, BYTE** dec_data, int* res_length);
#endif /* FREERDP_CRYPTO_H */

View File

@ -80,7 +80,8 @@ if(WITH_NEON)
endif()
if(WITH_JPEG)
set(FREERDP_JPEG_LIBS jpeg)
include_directories(${JPEG_INCLUDE_DIR})
set(FREERDP_JPEG_LIBS ${JPEG_LIBRARIES})
endif()
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"

View File

@ -106,7 +106,7 @@ int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
goto out;
ntlm_token_data = NULL;
crypto_base64_decode((BYTE*) token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
}
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
@ -238,7 +238,7 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{
char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
crypto_base64_decode((BYTE*) token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
}
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;

View File

@ -300,27 +300,25 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX;
auth_3_pdu->call_id = 2;
offset = 20;
auth_3_pdu->max_xmit_frag = rpc->max_xmit_frag;
auth_3_pdu->max_recv_frag = rpc->max_recv_frag;
offset += 4;
offset = 20;
auth_3_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
auth_3_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
auth_3_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
auth_3_pdu->auth_verifier.auth_reserved = 0x00;
auth_3_pdu->auth_verifier.auth_context_id = 0x00000000;
offset += (8 + auth_3_pdu->auth_length);
auth_3_pdu->frag_length = 20 + 4 +
auth_3_pdu->auth_verifier.auth_pad_length + auth_3_pdu->auth_length + 8;
auth_3_pdu->frag_length = offset;
buffer = (BYTE*) malloc(auth_3_pdu->frag_length);
CopyMemory(buffer, auth_3_pdu, 24);
CopyMemory(buffer, auth_3_pdu, 20);
offset = 24;
offset = 20;
rpc_offset_pad(&offset, auth_3_pdu->auth_verifier.auth_pad_length);
CopyMemory(&buffer[offset], &auth_3_pdu->auth_verifier.auth_type, 8);

View File

@ -704,9 +704,19 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
if (nego->RoutingToken)
{
Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
Stream_Write_UINT8(s, 0x0D); /* CR */
Stream_Write_UINT8(s, 0x0A); /* LF */
length += nego->RoutingTokenLength + 2;
/* Ensure Routing Token is correctly terminated - may already be present in string */
if (nego->RoutingTokenLength>2 && (nego->RoutingToken[nego->RoutingTokenLength-2]==0x0D && nego->RoutingToken[nego->RoutingTokenLength-1]==0x0A))
{
DEBUG_NEGO("Routing token looks correctly terminated - use verbatim");
length +=nego->RoutingTokenLength;
}
else
{
DEBUG_NEGO("Adding terminating CRLF to routing token");
Stream_Write_UINT8(s, 0x0D); /* CR */
Stream_Write_UINT8(s, 0x0A); /* LF */
length += nego->RoutingTokenLength + 2;
}
}
else if (nego->cookie)
{

View File

@ -40,6 +40,12 @@
#include <netinet/tcp.h>
#include <net/if.h>
#ifdef __FreeBSD__
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
#endif
#ifdef __APPLE__
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP

View File

@ -71,3 +71,7 @@ else()
endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -34,38 +34,56 @@ char* crypto_base64_encode(const BYTE* data, int length)
char* p;
char* ret;
int i = 0;
int blocks;
q = data;
p = ret = (char*) malloc((length + 3) * 4 / 3 + 1);
if (!p)
return NULL;
while (i < length)
/* b1, b2, b3 are input bytes
*
* 0 1 2
* 012345678901234567890123
* | b1 | b2 | b3 |
*
* [ c1 ] [ c3 ]
* [ c2 ] [ c4 ]
*
* c1, c2, c3, c4 are output chars in base64
*/
/* first treat complete blocks */
blocks = length - (length % 3);
for (i = 0; i < blocks; i += 3, q += 3)
{
c = q[i++];
c <<= 8;
if (i < length)
c += q[i];
i++;
c <<= 8;
if (i < length)
c += q[i];
i++;
c = (q[0] << 16) + (q[1] << 8) + q[2];
*p++ = base64[(c & 0x00FC0000) >> 18];
*p++ = base64[(c & 0x0003F000) >> 12];
*p++ = base64[(c & 0x00000FC0) >> 6];
*p++ = base64[c & 0x0000003F];
}
if (i > length + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000FC0) >> 6];
if (i > length)
*p++ = '=';
else
*p++ = base64[c & 0x0000003F];
/* then remainder */
switch (length % 3)
{
case 0:
break;
case 1:
c = (q[0] << 16);
*p++ = base64[(c & 0x00FC0000) >> 18];
*p++ = base64[(c & 0x0003F000) >> 12];
*p++ = '=';
*p++ = '=';
break;
case 2:
c = (q[0] << 16) + (q[1] << 8);
*p++ = base64[(c & 0x00FC0000) >> 18];
*p++ = base64[(c & 0x0003F000) >> 12];
*p++ = base64[(c & 0x00000FC0) >> 6];
*p++ = '=';
break;
}
*p = 0;
@ -96,55 +114,82 @@ static int base64_decode_char(char c)
return -1;
}
static void* base64_decode(const BYTE* s, int length, int* data_len)
static void* base64_decode(const char* s, int length, int* data_len)
{
char* p;
int n[4];
BYTE* q;
BYTE* data;
int nBlocks, i, outputLen;
if (length % 4)
return NULL;
n[0] = n[1] = n[2] = n[3] = 0;
q = data = (BYTE*) malloc(length / 4 * 3);
for (p = (char*) s; *p; )
/* first treat complete blocks */
nBlocks = (length / 4);
outputLen = 0;
for (i = 0; i < nBlocks-1; i++, q += 3)
{
n[0] = base64_decode_char(*p++);
n[1] = base64_decode_char(*p++);
n[2] = base64_decode_char(*p++);
n[3] = base64_decode_char(*p++);
n[0] = base64_decode_char(*s++);
n[1] = base64_decode_char(*s++);
n[2] = base64_decode_char(*s++);
n[3] = base64_decode_char(*s++);
if ((n[0] == -1) || (n[1] == -1))
{
free(data);
return NULL;
}
if ((n[2] == -1) && (n[3] != -1))
{
free(data);
return NULL;
}
if ((n[0] == -1) || (n[1] == -1) || (n[2] == -1) || (n[3] == -1))
goto out_free;
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1)
q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1)
q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
q[2] = ((n[2] & 3) << 6) + n[3];
outputLen += 3;
}
*data_len = q - data - (n[2] == -1) - (n[3] == -1);
/* treat last block */
n[0] = base64_decode_char(*s++);
n[1] = base64_decode_char(*s++);
if ((n[0] == -1) || (n[1] == -1))
goto out_free;
n[2] = base64_decode_char(*s++);
n[3] = base64_decode_char(*s++);
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] == -1)
{
/* XX== */
outputLen += 1;
if (n[3] != -1)
goto out_free;
q[1] = ((n[1] & 15) << 4);
}
else if (n[3] == -1)
{
/* yyy= */
outputLen += 2;
q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
q[2] = ((n[2] & 3) << 6);
}
else
{
/* XXXX */
outputLen += 3;
q[0] = (n[0] << 2) + (n[1] >> 4);
q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
q[2] = ((n[2] & 3) << 6) + n[3];
}
*data_len = outputLen;
return data;
out_free:
free(data);
return NULL;
}
void crypto_base64_decode(const BYTE* enc_data, int length, BYTE** dec_data, int* res_length)
void crypto_base64_decode(const char* enc_data, int length, BYTE** dec_data, int* res_length)
{
*dec_data = base64_decode(enc_data, length, res_length);
}

View File

@ -0,0 +1,31 @@
set(MODULE_NAME "TestFreeRDPCrypto")
set(MODULE_PREFIX "TEST_FREERDP_CRYPTO")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestBase64.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-crypto)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
foreach(test ${${MODULE_PREFIX}_TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test")

View File

@ -0,0 +1,110 @@
/**
* Copyright © 2014 Thincast Technologies GmbH
* Copyright © 2014 Hardening <contact@hardening-consulting.com>
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <freerdp/crypto/crypto.h>
struct Encode64test {
const char *input;
int len;
const char *output;
};
struct Encode64test encodeTests[] = {
{"\x00", 1, "AA=="},
{"\x00\x00", 2, "AAA="},
{"\x00\x00\x00", 3, "AAAA"},
{"0123456", 7, "MDEyMzQ1Ng=="},
{"90123456", 8, "OTAxMjM0NTY="},
{"890123456", 9, "ODkwMTIzNDU2"},
{"7890123456", 10, "Nzg5MDEyMzQ1Ng=="},
{NULL, -1, NULL}, /* /!\ last one /!\ */
};
int TestBase64(int argc, char* argv[])
{
int i, testNb = 0;
int outLen;
BYTE *decoded;
testNb++;
fprintf(stderr, "%d:encode base64...", testNb);
for (i = 0; encodeTests[i].input; i++)
{
char *encoded = crypto_base64_encode((const BYTE *)encodeTests[i].input, encodeTests[i].len);
if (strcmp(encodeTests[i].output, encoded))
{
fprintf(stderr, "ko, error for string %d\n", i);
return -1;
}
free(encoded);
}
fprintf(stderr, "ok\n");
testNb++;
fprintf(stderr, "%d:decode base64...", testNb);
for (i = 0; encodeTests[i].input; i++)
{
crypto_base64_decode(encodeTests[i].output, strlen(encodeTests[i].output), &decoded, &outLen);
if (!decoded || (outLen != encodeTests[i].len) || memcmp(encodeTests[i].input, decoded, outLen))
{
fprintf(stderr, "ko, error for string %d\n", i);
return -1;
}
free(decoded);
}
fprintf(stderr, "ok\n");
testNb++;
fprintf(stderr, "%d:decode base64 errors...", testNb);
crypto_base64_decode("000", 3, &decoded, &outLen);
if (decoded)
{
fprintf(stderr, "ko, badly padded string\n");
return -1;
}
crypto_base64_decode("0=00", 4, &decoded, &outLen);
if (decoded)
{
fprintf(stderr, "ko, = in a wrong place\n");
return -1;
}
crypto_base64_decode("00=0", 4, &decoded, &outLen);
if (decoded)
{
fprintf(stderr, "ko, = in a wrong place\n");
return -1;
}
fprintf(stderr, "ok\n");
return 0;
}

View File

@ -31,6 +31,10 @@
#include <freerdp/crypto/tls.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer)
{
CryptoCert cert;
@ -465,6 +469,10 @@ int tls_read(rdpTls* tls, BYTE* data, int length)
}
}
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(data, status);
#endif
return status;
}

View File

@ -1663,7 +1663,12 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
local_time = localtime(&t);
#ifdef HAVE_TM_GMTOFF
clientTimeZone->bias = timezone / 60;
#if defined(__FreeBSD__)
/*not the best solution, but could not get the right tyepcast*/
clientTimeZone->bias = 0;
#else
clientTimeZone->bias = timezone / 60;
#endif
DEBUG_TIMEZONE("tzname[std]: %s, tzname[dst]: %s, timezone: %ld, Daylight: %d", tzname[0], tzname[1], timezone, daylight);
#elif defined(sun)
if (local_time->tm_isdst > 0)

View File

@ -6,15 +6,19 @@
# Specifically these are:
# - OpenSSL
# - Android NDK Profiler
# - Jpeg library
#
# Usage:
# android_setup_build_env.sh <source root>
OPENSSL_SCM=https://github.com/akallabeth/openssl-android
NDK_PROFILER_SCM=https://github.com/richq/android-ndk-profiler
OPENSSL_SCM=https://github.com/akallabeth/openssl-android.git
NDK_PROFILER_SCM=https://github.com/richq/android-ndk-profiler.git
JPEG_LIBRARY_SCM=https://github.com/akallabeth/jpeg8d.git
SCRIPT_NAME=`basename $0`
if [ $# -ne 1 ]; then
echo "Missing command line argument, current directory as root."
ROOT=`pwd`
ROOT=$ROOT/external
@ -42,27 +46,30 @@ if [ $RETVAL -ne 0 ]; then
echo "Failed to execute git command [$RETVAL]"
exit -3
fi
cd $OPENSSL_SRC
make clean
# The makefile has a bug, which aborts during
# first compilation. Rerun make to build the whole lib.
make
make
make
RETVAL=0 # TODO: Check, why 2 is returned.
if [ $RETVAL -ne 0 ]; then
echo "Failed to execute make command [$RETVAL]"
exit -4
fi
# Copy the created library to the default openssl directory,
# so that CMake will detect it automatically.
SSL_ROOT=`find $OPENSSL_SRC -type d -name "openssl-?.?.*"`
if [ -z "$SSL_ROOT" ]; then
echo "OpenSSL was not build successfully, aborting."
exit -42
fi
mkdir -p $SSL_ROOT/lib
cp $SSL_ROOT/*.a $SSL_ROOT/lib/
rm -f $ROOT/openssl
ln -s $SSL_ROOT $ROOT/openssl
mkdir -p $ROOT/openssl/obj/local/armeabi/
cp $ROOT/openssl/libssl.a $ROOT/openssl/obj/local/armeabi/
cp $ROOT/openssl/libcrypto.a $ROOT/openssl/obj/local/armeabi/
echo "Preparing NDK profiler..."
NDK_PROFILER_SRC=$ROOT/android-ndk-profiler
@ -87,5 +94,30 @@ if [ $RETVAL -ne 0 ]; then
exit -6
fi
echo "Preparing JPEG library..."
JPEG_LIBRARY_SRC=$ROOT/jpeg8d
if [ -d $JPEG_LIBRARY_SRC ]; then
cd $JPEG_LIBRARY_SRC
git pull
RETVAL=$?
else
git clone $JPEG_LIBRARY_SCM $JPEG_LIBRARY_SRC
RETVAL=$?
fi
if [ $RETVAL -ne 0 ]; then
echo "Failed to execute git command [$RETVAL]"
exit -6
fi
cd $JPEG_LIBRARY_SRC
ndk-build V=1 APP_ABI=armeabi-v7a clean
ndk-build V=1 APP_ABI=armeabi-v7a
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
echo "Failed to execute ndk-build command [$RETVAL]"
exit -7
fi
mkdir -p $JPEG_LIBRARY_SRC/lib
cp $JPEG_LIBRARY_SRC/obj/local/armeabi-v7a/*.a $JPEG_LIBRARY_SRC/lib/
echo "Prepared external libraries, you can now build the application."
exit 0

View File

@ -31,6 +31,8 @@
#ifdef __APPLE__
#include <malloc/malloc.h>
#elif __FreeBSD__
#include <stdlib.h>
#else
#include <malloc.h>
#endif

View File

@ -124,7 +124,12 @@ static int pthread_timedjoin_np(pthread_t td, void **res,
return ETIMEDOUT;
}
static int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout)
#if defined(__FreeBSD__)
/*the only way to get it work is to remove the static*/
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout)
#else
static int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout)
#endif
{
struct timespec timenow;
struct timespec sleepytime;

View File

@ -129,7 +129,11 @@ static DWORD GetNumberOfProcessors()
size_t length = sizeof(numCPUs);
mib[0] = CTL_HW;
mib[1] = HW_AVAILCPU;
#if defined(__FreeBSD__)
mib[1] = HW_NCPU;
#else
mib[1] = HW_AVAILCPU;
#endif
sysctl(mib, 2, &numCPUs, &length, NULL, 0);