New upstream version 2.5.0+dfsg1

This commit is contained in:
Mike Gabriel 2022-02-14 08:03:24 +01:00
parent 4e5cdbea0a
commit 1aaad2c68f
34 changed files with 890 additions and 284 deletions

View File

@ -85,7 +85,7 @@ if ($ENV{BUILD_NUMBER})
endif()
set(WITH_LIBRARY_VERSIONING "ON")
set(RAW_VERSION_STRING "2.4.1")
set(RAW_VERSION_STRING "2.5.0")
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)

View File

@ -1,3 +1,25 @@
# 2022-01-12 Version 2.5.0
Noteworthy changes:
* Fixed smartcard login in case a redirection occurs the pin was lost
* Backported windows client drawing fixes
* Backported improved macOS keyboard layout detection
* Backported TcpConnectTimeout
* Backported LibreSSL compatibility patches
* Backported signal handler backtrace
* Backported OpenSSL 3.0 support
Fixed issues:
* Backport #7539: Wayland client clipboard issues
* Backport #7509: Various fixes regarding registry emulation, addin loader
and updated locale detection
* Backport #7466: Android android_register_pointer missing initialization
Important notes:
For a complete and detailed change log since the last release run:
git log 2.4.1..2.5.0
# 2021-10-20 Version 2.4.1
Noteworthy changes:

View File

@ -248,7 +248,7 @@ static UINT audin_opensles_parse_addin_args(AudinOpenSLESDevice* device, ADDIN_A
{
UINT status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
const COMMAND_LINE_ARGUMENT_A* arg;
AudinOpenSLESDevice* opensles = (AudinOpenSLESDevice*)device;
COMMAND_LINE_ARGUMENT_A audin_opensles_args[] = {
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL,

View File

@ -231,10 +231,8 @@ static FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPCSTR pszName, LPCS
do
{
char* p[5];
FREERDP_ADDIN* pAddin;
nDashes = 0;
pAddin = (FREERDP_ADDIN*)calloc(1, sizeof(FREERDP_ADDIN));
BOOL used = FALSE;
FREERDP_ADDIN* pAddin = (FREERDP_ADDIN*)calloc(1, sizeof(FREERDP_ADDIN));
if (!pAddin)
{
@ -242,57 +240,116 @@ static FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPCSTR pszName, LPCS
goto error_out;
}
nDashes = 0;
for (index = 0; FindData.cFileName[index]; index++)
nDashes += (FindData.cFileName[index] == '-') ? 1 : 0;
if (nDashes == 1)
{
size_t len;
char* p[2] = { 0 };
/* <name>-client.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
len = p[1] - p[0];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else if (nDashes == 2)
{
size_t len;
char* p[4] = { 0 };
/* <name>-client-<subsystem>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '.') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
len = p[1] - p[0];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
len = p[3] - p[2];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cSubsystem, p[2], MIN(ARRAYSIZE(pAddin->cSubsystem), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else if (nDashes == 3)
{
size_t len;
char* p[5] = { 0 };
/* <name>-client-<subsystem>-<type>.<extension> */
p[0] = FindData.cFileName;
p[1] = strchr(p[0], '-') + 1;
p[2] = strchr(p[1], '-') + 1;
p[3] = strchr(p[2], '-') + 1;
p[4] = strchr(p[3], '.') + 1;
strncpy(pAddin->cName, p[0], (p[1] - p[0]) - 1);
strncpy(pAddin->cSubsystem, p[2], (p[3] - p[2]) - 1);
strncpy(pAddin->cType, p[3], (p[4] - p[3]) - 1);
len = p[1] - p[0];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cName, p[0], MIN(ARRAYSIZE(pAddin->cName), len - 1));
len = p[3] - p[2];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cSubsystem, p[2], MIN(ARRAYSIZE(pAddin->cSubsystem), len - 1));
len = p[4] - p[3];
if (len < 1)
{
WLog_WARN(TAG, "Skipping file '%s', invalid format", FindData.cFileName);
goto skip;
}
strncpy(pAddin->cType, p[3], MIN(ARRAYSIZE(pAddin->cType), len - 1));
pAddin->dwFlags = FREERDP_ADDIN_CLIENT;
pAddin->dwFlags |= FREERDP_ADDIN_DYNAMIC;
pAddin->dwFlags |= FREERDP_ADDIN_NAME;
pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM;
pAddin->dwFlags |= FREERDP_ADDIN_TYPE;
ppAddins[nAddins++] = pAddin;
used = TRUE;
}
else
{
skip:
if (!used)
free(pAddin);
}
} while (FindNextFileA(hFind, &FindData));
FindClose(hFind);

View File

@ -58,7 +58,7 @@ static wStream* disp_server_single_packet_new(UINT32 type, UINT32 length)
}
header.type = type;
header.length = length;
header.length = DISPLAY_CONTROL_HEADER_LENGTH + length;
if ((error = disp_write_header(s, &header)))
{

View File

@ -1386,7 +1386,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
return CHANNEL_RC_OK;
error_out:
free(context);
free(rdpei->contactPoints);
free(rdpei);
return error;
}

View File

@ -80,6 +80,7 @@ struct wlf_clipboard
FILE* responseFile;
UINT32 responseFormat;
const char* responseMime;
CRITICAL_SECTION lock;
};
static BOOL wlf_mime_is_text(const char* mime)
@ -275,7 +276,7 @@ BOOL wlf_cliprdr_handle_event(wfClipboard* clipboard, const UwacClipboardEvent*
return TRUE;
case UWAC_EVENT_CLIPBOARD_OFFER:
WLog_Print(clipboard->log, WLOG_INFO, "client announces mime %s", event->mime);
WLog_Print(clipboard->log, WLOG_DEBUG, "client announces mime %s", event->mime);
wlf_cliprdr_add_client_format(clipboard, event->mime);
return TRUE;
@ -387,6 +388,8 @@ static void wlf_cliprdr_transfer_data(UwacSeat* seat, void* context, const char*
wfClipboard* clipboard = (wfClipboard*)context;
size_t x;
WINPR_UNUSED(seat);
EnterCriticalSection(&clipboard->lock);
clipboard->responseMime = NULL;
for (x = 0; x < ARRAYSIZE(mime_html); x++)
@ -427,6 +430,8 @@ static void wlf_cliprdr_transfer_data(UwacSeat* seat, void* context, const char*
if (clipboard->responseMime != NULL)
{
if (clipboard->responseFile != NULL)
fclose(clipboard->responseFile);
clipboard->responseFile = fdopen(fd, "w");
if (clipboard->responseFile)
@ -436,6 +441,7 @@ static void wlf_cliprdr_transfer_data(UwacSeat* seat, void* context, const char*
"failed to open clipboard file descriptor for MIME %s",
clipboard->responseMime);
}
LeaveCriticalSection(&clipboard->lock);
}
static void wlf_cliprdr_cancel_data(UwacSeat* seat, void* context)
@ -673,6 +679,8 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context,
const WCHAR* wdata = (const WCHAR*)formatDataResponse->requestedFormatData;
wfClipboard* clipboard = (wfClipboard*)context->custom;
EnterCriticalSection(&clipboard->lock);
if (size > INT_MAX * sizeof(WCHAR))
return ERROR_INTERNAL_ERROR;
@ -694,10 +702,16 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context,
break;
}
fwrite(data, 1, size, clipboard->responseFile);
fclose(clipboard->responseFile);
if (clipboard->responseFile)
{
fwrite(data, 1, size, clipboard->responseFile);
fclose(clipboard->responseFile);
clipboard->responseFile = NULL;
}
rc = CHANNEL_RC_OK;
free(cdata);
LeaveCriticalSection(&clipboard->lock);
return rc;
}
@ -829,17 +843,24 @@ static UINT wlf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegat
wfClipboard* wlf_clipboard_new(wlfContext* wfc)
{
rdpChannels* channels;
wfClipboard* clipboard;
wfClipboard* clipboard = (wfClipboard*)calloc(1, sizeof(wfClipboard));
if (!(clipboard = (wfClipboard*)calloc(1, sizeof(wfClipboard))))
return NULL;
if (!clipboard)
goto fail;
InitializeCriticalSection(&clipboard->lock);
clipboard->wfc = wfc;
channels = wfc->context.channels;
clipboard->log = WLog_Get(TAG);
clipboard->channels = channels;
clipboard->system = ClipboardCreate();
if (!clipboard->system)
goto fail;
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
if (!clipboard->delegate)
goto fail;
clipboard->delegate->custom = clipboard;
/* TODO: set up a filesystem base path for local URI */
/* clipboard->delegate->basePath = "file:///tmp/foo/bar/gaga"; */
@ -848,6 +869,10 @@ wfClipboard* wlf_clipboard_new(wlfContext* wfc)
clipboard->delegate->ClipboardFileRangeSuccess = wlf_cliprdr_clipboard_file_range_success;
clipboard->delegate->ClipboardFileRangeFailure = wlf_cliprdr_clipboard_file_range_failure;
return clipboard;
fail:
wlf_clipboard_free(clipboard);
return NULL;
}
void wlf_clipboard_free(wfClipboard* clipboard)
@ -858,6 +883,12 @@ void wlf_clipboard_free(wfClipboard* clipboard)
wlf_cliprdr_free_server_formats(clipboard);
wlf_cliprdr_free_client_formats(clipboard);
ClipboardDestroy(clipboard->system);
EnterCriticalSection(&clipboard->lock);
if (clipboard->responseFile)
fclose(clipboard->responseFile);
LeaveCriticalSection(&clipboard->lock);
DeleteCriticalSection(&clipboard->lock);
free(clipboard);
}

View File

@ -331,12 +331,15 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
break;
case UWAC_EVENT_FRAME_DONE:
{
UwacReturnCode r;
EnterCriticalSection(&context->critical);
rc = UwacWindowSubmitBuffer(context->window, false);
r = UwacWindowSubmitBuffer(context->window, false);
LeaveCriticalSection(&context->critical);
if (rc != UWAC_SUCCESS)
if (r != UWAC_SUCCESS)
return FALSE;
break;
}
break;
case UWAC_EVENT_POINTER_ENTER:
if (!wlf_handle_pointer_enter(instance, &event.mouse_enter_leave))

View File

@ -62,6 +62,7 @@
#define BRETON 0x047E
#define BULGARIAN 0x0402
#define CATALAN 0x0403
#define CHEROKEE 0x045C
#define CHINESE_TAIWAN 0x0404
#define CHINESE_PRC 0x0804
#define CHINESE_HONG_KONG 0x0C04
@ -113,12 +114,14 @@
#define GREEK 0x0408
#define GREENLANDIC 0x046F
#define GUJARATI 0x0447
#define HAWAIIAN 0x0475
#define HEBREW 0x040D
#define HINDI 0x0439
#define HUNGARIAN 0x040E
#define ICELANDIC 0x040F
#define IGBO 0x0470
#define INDONESIAN 0x0421
#define INUKTITUT 0x045D
#define IRISH 0x083C
#define ITALIAN_STANDARD 0x0410
#define ITALIAN_SWISS 0x0810
@ -146,6 +149,7 @@
#define MARATHI 0x044E
#define MOHAWK 0x047C
#define MONGOLIAN 0x0450
#define MYANMAR 0x0455
#define NEPALI 0x0461
#define NORWEGIAN_BOKMAL 0x0414
#define NORWEGIAN_NYNORSK 0x0814

View File

@ -894,6 +894,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_TcpKeepAliveDelay (5192)
#define FreeRDP_TcpKeepAliveInterval (5193)
#define FreeRDP_TcpAckTimeout (5194)
#define FreeRDP_TcpConnectTimeout (5197)
/**
* FreeRDP Settings Data Structure
@ -1342,20 +1343,20 @@ struct rdp_settings
/* Input Capabilities */
ALIGN64 char* KeyboardRemappingList; /* 2622 */
ALIGN64 UINT32 KeyboardCodePage; /* 2623 */
ALIGN64 UINT32 KeyboardLayout; /* 2624 */
ALIGN64 UINT32 KeyboardType; /* 2625 */
ALIGN64 UINT32 KeyboardSubType; /* 2626 */
ALIGN64 UINT32 KeyboardFunctionKey; /* 2627 */
ALIGN64 char* ImeFileName; /* 2628 */
ALIGN64 BOOL UnicodeInput; /* 2629 */
ALIGN64 BOOL FastPathInput; /* 2630 */
ALIGN64 BOOL MultiTouchInput; /* 2631 */
ALIGN64 BOOL MultiTouchGestures; /* 2632 */
ALIGN64 UINT32 KeyboardHook; /* 2633 */
ALIGN64 BOOL HasHorizontalWheel; /* 2634 */
ALIGN64 BOOL HasExtendedMouseEvent; /* 2635 */
UINT64 padding2688[2688 - 2636]; /* 2636 */
ALIGN64 UINT32 KeyboardCodePage; /* 2623 */
ALIGN64 UINT32 KeyboardLayout; /* 2624 */
ALIGN64 UINT32 KeyboardType; /* 2625 */
ALIGN64 UINT32 KeyboardSubType; /* 2626 */
ALIGN64 UINT32 KeyboardFunctionKey; /* 2627 */
ALIGN64 char* ImeFileName; /* 2628 */
ALIGN64 BOOL UnicodeInput; /* 2629 */
ALIGN64 BOOL FastPathInput; /* 2630 */
ALIGN64 BOOL MultiTouchInput; /* 2631 */
ALIGN64 BOOL MultiTouchGestures; /* 2632 */
ALIGN64 UINT32 KeyboardHook; /* 2633 */
ALIGN64 BOOL HasHorizontalWheel; /* 2634 */
ALIGN64 BOOL HasExtendedMouseEvent; /* 2635 */
UINT64 padding2688[2688 - 2636]; /* 2636 */
/* Brush Capabilities */
ALIGN64 UINT32 BrushSupportLevel; /* 2688 */
@ -1545,7 +1546,9 @@ struct rdp_settings
ALIGN64 UINT32 TcpKeepAliveDelay; /* 5192 */
ALIGN64 UINT32 TcpKeepAliveInterval; /* 5193 */
ALIGN64 UINT32 TcpAckTimeout; /* 5194 */
UINT64 padding5312[5312 - 5195]; /* 5195 */
UINT64 padding5197[5197 - 5195]; /* 5195 */
ALIGN64 UINT32 TcpConnectTimeout; /* 5197 */
UINT64 padding5312[5312 - 5198]; /* 5198 */
/**
* WARNING: End of ABI stable zone!

View File

@ -263,6 +263,7 @@ struct rdp_update
* fills BITMAP_DATA struct members: flags, cbCompMainBodySize and cbCompFirstRowSize.
*/
BOOL autoCalculateBitmapData;
size_t offsetOrders; /* the offset to patch numberOrders in the stream */
};
#endif /* FREERDP_UPDATE_H */

View File

@ -1570,6 +1570,9 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, size_t id)
case FreeRDP_TcpAckTimeout:
return settings->TcpAckTimeout;
case FreeRDP_TcpConnectTimeout:
return settings->TcpConnectTimeout;
case FreeRDP_TcpKeepAliveDelay:
return settings->TcpKeepAliveDelay;
@ -2021,6 +2024,10 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, size_t id, UINT32 val)
settings->TcpAckTimeout = val;
break;
case FreeRDP_TcpConnectTimeout:
settings->TcpConnectTimeout = val;
break;
case FreeRDP_TcpKeepAliveDelay:
settings->TcpKeepAliveDelay = val;
break;

View File

@ -285,6 +285,7 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_StaticChannelCount, 3, "FreeRDP_StaticChannelCount" },
{ FreeRDP_TargetNetAddressCount, 3, "FreeRDP_TargetNetAddressCount" },
{ FreeRDP_TcpAckTimeout, 3, "FreeRDP_TcpAckTimeout" },
{ FreeRDP_TcpConnectTimeout, 3, "FreeRDP_TcpConnectTimeout" },
{ FreeRDP_TcpKeepAliveDelay, 3, "FreeRDP_TcpKeepAliveDelay" },
{ FreeRDP_TcpKeepAliveInterval, 3, "FreeRDP_TcpKeepAliveInterval" },
{ FreeRDP_TcpKeepAliveRetries, 3, "FreeRDP_TcpKeepAliveRetries" },

View File

@ -105,7 +105,7 @@ BOOL rpc_ncacn_http_send_in_channel_request(RpcChannel* inChannel)
BOOL rpc_ncacn_http_recv_in_channel_response(RpcChannel* inChannel, HttpResponse* response)
{
const char* token64 = NULL;
size_t ntlmTokenLength = 0;
int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL;
rdpNtlm* ntlm;
@ -259,7 +259,7 @@ BOOL rpc_ncacn_http_send_out_channel_request(RpcChannel* outChannel, BOOL replac
BOOL rpc_ncacn_http_recv_out_channel_response(RpcChannel* outChannel, HttpResponse* response)
{
const char* token64 = NULL;
size_t ntlmTokenLength = 0;
int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL;
rdpNtlm* ntlm;

View File

@ -1190,7 +1190,7 @@ static BOOL rdg_handle_ntlm_challenge(rdpNtlm* ntlm, HttpResponse* response)
BOOL continueNeeded = FALSE;
size_t len;
const char* token64 = NULL;
size_t ntlmTokenLength = 0;
int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL;
long StatusCode;

View File

@ -711,7 +711,9 @@ static BOOL rdp_write_info_packet(rdpRdp* rdp, wStream* s)
if (!settings->RemoteAssistanceMode)
{
if (settings->RedirectionPassword && settings->RedirectionPasswordLength > 0)
/* Ignore redirection password if we´re using smartcard and have the pin as password */
if (((flags & INFO_PASSWORD_IS_SC_PIN) == 0) && settings->RedirectionPassword &&
(settings->RedirectionPasswordLength > 0))
{
union {
BYTE* bp;

View File

@ -277,6 +277,9 @@ static BOOL nego_tcp_connect(rdpNego* nego)
{
if (!nego->TcpConnected)
{
const UINT32 TcpConnectTimeout = freerdp_settings_get_uint32(
nego->transport->context->settings, FreeRDP_TcpConnectTimeout);
if (nego->GatewayEnabled)
{
if (nego->GatewayBypassLocal)
@ -286,20 +289,21 @@ static BOOL nego_tcp_connect(rdpNego* nego)
"Detecting if host can be reached locally. - This might take some time.");
WLog_INFO(TAG, "To disable auto detection use /gateway-usage-method:direct");
transport_set_gateway_enabled(nego->transport, FALSE);
nego->TcpConnected =
transport_connect(nego->transport, nego->hostname, nego->port, 1);
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
TcpConnectTimeout);
}
if (!nego->TcpConnected)
{
transport_set_gateway_enabled(nego->transport, TRUE);
nego->TcpConnected =
transport_connect(nego->transport, nego->hostname, nego->port, 15);
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port,
TcpConnectTimeout);
}
}
else
{
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
nego->TcpConnected =
transport_connect(nego->transport, nego->hostname, nego->port, TcpConnectTimeout);
}
}

View File

@ -547,11 +547,13 @@ rdpSettings* freerdp_settings_new(DWORD flags)
if (!settings->DynamicChannelArray)
goto out_fail;
settings->TcpKeepAlive = TRUE;
settings->TcpKeepAliveRetries = 3;
settings->TcpKeepAliveDelay = 5;
settings->TcpKeepAliveInterval = 2;
settings->TcpAckTimeout = 9000;
if (!freerdp_settings_set_bool(settings, FreeRDP_TcpKeepAlive, TRUE) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpKeepAliveRetries, 3) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpKeepAliveDelay, 5) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpKeepAliveInterval, 2) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpAckTimeout, 9000) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpConnectTimeout, 15000))
goto out_fail;
if (!settings->ServerMode)
{

View File

@ -801,14 +801,14 @@ static BOOL freerdp_tcp_is_hostname_resolvable(rdpContext* context, const char*
}
static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct sockaddr* addr,
socklen_t addrlen, int timeout)
socklen_t addrlen, UINT32 timeout)
{
BOOL rc = FALSE;
HANDLE handles[2];
int status = 0;
int count = 0;
u_long arg = 0;
DWORD tout = (timeout > 0) ? (DWORD)timeout * 1000U : INFINITE;
DWORD tout = (timeout > 0) ? timeout : INFINITE;
handles[count] = CreateEvent(NULL, TRUE, FALSE, NULL);
@ -894,7 +894,7 @@ static void peer_free(t_peer* peer)
}
static int freerdp_tcp_connect_multi(rdpContext* context, char** hostnames, UINT32* ports,
UINT32 count, int port, int timeout)
UINT32 count, UINT16 port, UINT32 timeout)
{
UINT32 index;
UINT32 sindex = count;

View File

@ -282,6 +282,7 @@ static const size_t uint32_list_indices[] = {
FreeRDP_StaticChannelCount,
FreeRDP_TargetNetAddressCount,
FreeRDP_TcpAckTimeout,
FreeRDP_TcpConnectTimeout,
FreeRDP_TcpKeepAliveDelay,
FreeRDP_TcpKeepAliveInterval,
FreeRDP_TcpKeepAliveRetries,

View File

@ -931,6 +931,7 @@ static BOOL _update_begin_paint(rdpContext* context)
return FALSE;
Stream_SealLength(s);
Stream_GetLength(s, update->offsetOrders);
Stream_Seek(s, 2); /* numberOrders (2 bytes) */
update->combineUpdates = TRUE;
update->numberOrders = 0;
@ -941,16 +942,14 @@ static BOOL _update_begin_paint(rdpContext* context)
static BOOL _update_end_paint(rdpContext* context)
{
wStream* s;
int headerLength;
rdpUpdate* update = context->update;
if (!update->us)
return FALSE;
s = update->us;
headerLength = Stream_Length(s);
Stream_SealLength(s);
Stream_SetPosition(s, headerLength);
Stream_SetPosition(s, update->offsetOrders);
Stream_Write_UINT16(s, update->numberOrders); /* numberOrders (2 bytes) */
Stream_SetPosition(s, Stream_Length(s));
@ -962,6 +961,7 @@ static BOOL _update_end_paint(rdpContext* context)
update->combineUpdates = FALSE;
update->numberOrders = 0;
update->offsetOrders = 0;
update->us = NULL;
Stream_Free(s, TRUE);
return TRUE;

View File

@ -323,7 +323,8 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr)
case BIO_CTRL_PUSH:
if (next_bio && (next_bio != ssl_rbio))
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
SSL_set_bio(tls->ssl, next_bio, next_bio);
CRYPTO_add(&(bio->next_bio->references), 1, CRYPTO_LOCK_BIO);
#else
@ -347,7 +348,8 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr)
if (ssl_rbio != ssl_wbio)
BIO_free_all(ssl_wbio);
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
if (next_bio)
CRYPTO_add(&(bio->next_bio->references), -1, CRYPTO_LOCK_BIO);
@ -387,7 +389,8 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr)
BIO_push(ssl_rbio, next_bio);
BIO_set_next(bio, ssl_rbio);
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
CRYPTO_add(&(ssl_rbio->references), 1, CRYPTO_LOCK_BIO);
#else
BIO_up_ref(ssl_rbio);

View File

@ -38,10 +38,20 @@ set(${MODULE_PREFIX}_SUN_SRCS
keyboard_sun.c
keyboard_sun.h)
set(${MODULE_PREFIX}_APPLE_SRCS
keyboard_apple.c
keyboard_apple.h)
if(CMAKE_SYSTEM_NAME MATCHES Solaris)
set(WITH_SUN true)
endif()
if(APPLE AND (NOT IOS))
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_APPLE_SRCS})
find_library(CARBON Carbon)
freerdp_library_add(${CARBON})
endif()
if(WITH_X11)
freerdp_definition_add(-DWITH_X11)
freerdp_include_directory_add(${X11_INCLUDE_DIRS})

View File

@ -32,6 +32,10 @@
#include "liblocale.h"
#if defined(__MACOSX__)
#include "keyboard_apple.h"
#endif
#ifdef WITH_X11
#include "keyboard_x11.h"
@ -64,6 +68,11 @@ int freerdp_detect_keyboard(DWORD* keyboardLayoutId)
*keyboardLayoutId = ((DWORD)GetKeyboardLayout(0) >> 16) & 0x0000FFFF;
#endif
#if defined(__MACOSX__)
if (*keyboardLayoutId == 0)
freerdp_detect_keyboard_layout_from_cf(keyboardLayoutId);
#endif
#ifdef WITH_X11
if (*keyboardLayoutId == 0)
freerdp_detect_keyboard_layout_from_xkb(keyboardLayoutId);
@ -148,7 +157,7 @@ DWORD freerdp_keyboard_init(DWORD keyboardLayoutId)
for (keycode = 0; keycode < ARRAYSIZE(VIRTUAL_SCANCODE_TO_X11_KEYCODE); keycode++)
{
VIRTUAL_SCANCODE_TO_X11_KEYCODE
[RDP_SCANCODE_CODE(X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode])]
[RDP_SCANCODE_CODE(X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode])]
[RDP_SCANCODE_EXTENDED(X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode]) ? 1 : 0] = keycode;
}

View File

@ -0,0 +1,244 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Apple Core Foundation Keyboard Mapping
*
* Copyright 2021 Thincast Technologies GmbH
* Copyright 2021 Martin Fleisz <martin.fleisz@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Carbon/Carbon.h>
#include <string.h>
#include "liblocale.h"
#include <freerdp/locale/locale.h>
#include <freerdp/locale/keyboard.h>
#include "keyboard_apple.h"
struct KEYBOARD_LAYOUT_MAPPING_
{
const char* inputSourceId; /* Apple input source id (com.apple.keylayout or inputmethod) */
DWORD code; /* mapped rdp keyboard layout id */
};
typedef struct KEYBOARD_LAYOUT_MAPPING_ KEYBOARD_LAYOUT_MAPPING;
static const KEYBOARD_LAYOUT_MAPPING KEYBOARD_MAPPING_TABLE[] = {
{ "com.apple.inputmethod.Kotoeri.Japanese", JAPANESE },
{ "com.apple.inputmethod.Kotoeri.Japanese.FullWidthRoman", JAPANESE },
{ "com.apple.inputmethod.Kotoeri.Japanese.HalfWidthKana", JAPANESE },
{ "com.apple.inputmethod.Kotoeri.Japanese.Katakana", JAPANESE },
{ "com.apple.inputmethod.Kotoeri.Katakana", JAPANESE },
{ "com.apple.inputmethod.Kotoeri.Roman", JAPANESE },
{ "com.apple.inputmethod.kotoeri.Ainu", JAPANESE },
{ "com.apple.keylayout.2SetHangul", KOREAN },
{ "com.apple.keylayout.390Hangul", KOREAN },
{ "com.apple.keylayout.3SetHangul", KOREAN },
{ "com.apple.keylayout.AfghanDari", DARI },
{ "com.apple.keylayout.AfghanPashto", PASHTO },
{ "com.apple.keylayout.AfghanUzbek", UZBEK_LATIN },
{ "com.apple.keylayout.Arabic", ARABIC_EGYPT },
{ "com.apple.keylayout.Arabic-QWERTY", ARABIC_EGYPT },
{ "com.apple.keylayout.ArabicPC", ARABIC_EGYPT },
{ "com.apple.keylayout.Armenian-HMQWERTY", ARMENIAN },
{ "com.apple.keylayout.Armenian-WesternQWERTY", ARMENIAN },
{ "com.apple.keylayout.Australian", ENGLISH_AUSTRALIAN },
{ "com.apple.keylayout.Austrian", GERMAN_AUSTRIAN },
{ "com.apple.keylayout.Azeri", AZERI_LATIN },
{ "com.apple.keylayout.Bangla", BENGALI_INDIA },
{ "com.apple.keylayout.Bangla-QWERTY", BENGALI_INDIA },
{ "com.apple.keylayout.Belgian", DUTCH_BELGIAN },
{ "com.apple.keylayout.Brazilian", PORTUGUESE_BRAZILIAN },
{ "com.apple.keylayout.British", ENGLISH_UNITED_KINGDOM },
{ "com.apple.keylayout.British-PC", ENGLISH_UNITED_KINGDOM },
{ "com.apple.keylayout.Bulgarian", BULGARIAN },
{ "com.apple.keylayout.Bulgarian-Phonetic", BULGARIAN },
{ "com.apple.keylayout.Byelorussian", BELARUSIAN },
{ "com.apple.keylayout.Canadian", ENGLISH_CANADIAN },
{ "com.apple.keylayout.Canadian-CSA", FRENCH_CANADIAN },
{ "com.apple.keylayout.CangjieKeyboard", CHINESE_TAIWAN },
{ "com.apple.keylayout.Cherokee-Nation", CHEROKEE },
{ "com.apple.keylayout.Cherokee-QWERTY", CHEROKEE },
{ "com.apple.keylayout.Colemak", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Croatian", CROATIAN },
{ "com.apple.keylayout.Croatian-PC", CROATIAN },
{ "com.apple.keylayout.Czech", CZECH },
{ "com.apple.keylayout.Czech-QWERTY", CZECH },
{ "com.apple.keylayout.DVORAK-QWERTYCMD", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Danish", DANISH },
{ "com.apple.keylayout.Devanagari", HINDI },
{ "com.apple.keylayout.Devanagari-QWERTY", HINDI },
{ "com.apple.keylayout.Dutch", DUTCH_STANDARD },
{ "com.apple.keylayout.Dvorak", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Dvorak-Left", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Dvorak-Right", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Estonian", ESTONIAN },
{ "com.apple.keylayout.Faroese", FAEROESE },
{ "com.apple.keylayout.Finnish", FINNISH },
{ "com.apple.keylayout.FinnishExtended", FINNISH },
{ "com.apple.keylayout.FinnishSami-PC", FINNISH },
{ "com.apple.keylayout.French", FRENCH_STANDARD },
{ "com.apple.keylayout.French-PC", FRENCH_STANDARD },
{ "com.apple.keylayout.French-numerical", FRENCH_STANDARD },
{ "com.apple.keylayout.GJCRomaja", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Georgian-QWERTY", GEORGIAN },
{ "com.apple.keylayout.German", GERMAN_STANDARD },
{ "com.apple.keylayout.Greek", GREEK },
{ "com.apple.keylayout.GreekPolytonic", GREEK },
{ "com.apple.keylayout.Gujarati", GUJARATI },
{ "com.apple.keylayout.Gujarati-QWERTY", GUJARATI },
{ "com.apple.keylayout.Gurmukhi", PUNJABI },
{ "com.apple.keylayout.Gurmukhi-QWERTY", PUNJABI },
{ "com.apple.keylayout.HNCRomaja", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Hawaiian", HAWAIIAN },
{ "com.apple.keylayout.Hebrew", HEBREW },
{ "com.apple.keylayout.Hebrew-PC", HEBREW },
{ "com.apple.keylayout.Hebrew-QWERTY", HEBREW },
{ "com.apple.keylayout.Hungarian", HUNGARIAN },
{ "com.apple.keylayout.Hungarian-QWERTY", HUNGARIAN },
{ "com.apple.keylayout.Icelandic", ICELANDIC },
{ "com.apple.keylayout.Inuktitut-Nunavut", INUKTITUT },
{ "com.apple.keylayout.Inuktitut-Nutaaq", INUKTITUT },
{ "com.apple.keylayout.Inuktitut-QWERTY", INUKTITUT },
{ "com.apple.keylayout.InuttitutNunavik", INUKTITUT },
{ "com.apple.keylayout.Irish", ENGLISH_IRELAND },
{ "com.apple.keylayout.IrishExtended", IRISH },
{ "com.apple.keylayout.Italian", ITALIAN_STANDARD },
{ "com.apple.keylayout.Italian-Pro", ITALIAN_STANDARD },
{ "com.apple.keylayout.Jawi-QWERTY", ARABIC_SAUDI_ARABIA },
{ "com.apple.keylayout.Kannada", KANNADA },
{ "com.apple.keylayout.Kannada-QWERTY", KANNADA },
{ "com.apple.keylayout.Kazakh", KAZAKH },
{ "com.apple.keylayout.Khmer", KHMER },
{ "com.apple.keylayout.Latvian", LATVIAN },
{ "com.apple.keylayout.Lithuanian", LITHUANIAN },
{ "com.apple.keylayout.Macedonian", MACEDONIAN },
{ "com.apple.keylayout.Malayalam", MALAYALAM },
{ "com.apple.keylayout.Malayalam-QWERTY", MALAYALAM },
{ "com.apple.keylayout.Maltese", MALTESE },
{ "com.apple.keylayout.Maori", MAORI },
{ "com.apple.keylayout.Myanmar-QWERTY", MYANMAR },
{ "com.apple.keylayout.Nepali", NEPALI },
{ "com.apple.keylayout.NorthernSami", SAMI_NORTHERN_NORWAY },
{ "com.apple.keylayout.Norwegian", NORWEGIAN_BOKMAL },
{ "com.apple.keylayout.NorwegianExtended", NORWEGIAN_BOKMAL },
{ "com.apple.keylayout.NorwegianSami-PC", NORWEGIAN_BOKMAL },
{ "com.apple.keylayout.Oriya", ORIYA },
{ "com.apple.keylayout.Persian", FARSI },
{ "com.apple.keylayout.Persian-ISIRI2901", FARSI },
{ "com.apple.keylayout.Polish", POLISH },
{ "com.apple.keylayout.PolishPro", POLISH },
{ "com.apple.keylayout.Portuguese", PORTUGUESE_STANDARD },
{ "com.apple.keylayout.Romanian", ROMANIAN },
{ "com.apple.keylayout.Romanian-Standard", ROMANIAN },
{ "com.apple.keylayout.Russian", RUSSIAN },
{ "com.apple.keylayout.Russian-Phonetic", RUSSIAN },
{ "com.apple.keylayout.RussianWin", RUSSIAN },
{ "com.apple.keylayout.Sami-PC", SAMI_NORTHERN_SWEDEN },
{ "com.apple.keylayout.Serbian", SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA },
{ "com.apple.keylayout.Serbian-Latin", SERBIAN_LATIN_BOSNIA_HERZEGOVINA },
{ "com.apple.keylayout.Sinhala", SINHALA },
{ "com.apple.keylayout.Sinhala-QWERTY", SINHALA },
{ "com.apple.keylayout.Slovak", SLOVAK },
{ "com.apple.keylayout.Slovak-QWERTY", SLOVAK },
{ "com.apple.keylayout.Slovenian", SLOVENIAN },
{ "com.apple.keylayout.Spanish", SPANISH_TRADITIONAL_SORT },
{ "com.apple.keylayout.Spanish-ISO", SPANISH_MODERN_SORT },
{ "com.apple.keylayout.Swedish", SWEDISH },
{ "com.apple.keylayout.Swedish-Pro", SWEDISH },
{ "com.apple.keylayout.SwedishSami-PC", SWEDISH },
{ "com.apple.keylayout.SwissFrench", FRENCH_SWISS },
{ "com.apple.keylayout.SwissGerman", GERMAN_SWISS },
{ "com.apple.keylayout.Telugu", TELUGU },
{ "com.apple.keylayout.Telugu-QWERTY", TELUGU },
{ "com.apple.keylayout.Thai", THAI },
{ "com.apple.keylayout.Thai-PattaChote", THAI },
{ "com.apple.keylayout.Tibetan-QWERTY", TIBETAN_PRC },
{ "com.apple.keylayout.Tibetan-Wylie", TIBETAN_PRC },
{ "com.apple.keylayout.TibetanOtaniUS", TIBETAN_PRC },
{ "com.apple.keylayout.Turkish", TURKISH },
{ "com.apple.keylayout.Turkish-QWERTY", TURKISH },
{ "com.apple.keylayout.Turkish-QWERTY-PC", TURKISH },
{ "com.apple.keylayout.US", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.USExtended", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.USInternational-PC", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Ukrainian", UKRAINIAN },
{ "com.apple.keylayout.Ukrainian-PC", UKRAINIAN },
{ "com.apple.keylayout.UnicodeHexInput", ENGLISH_UNITED_STATES },
{ "com.apple.keylayout.Urdu", URDU },
{ "com.apple.keylayout.Uyghur", UIGHUR },
{ "com.apple.keylayout.Vietnamese", VIETNAMESE },
{ "com.apple.keylayout.Welsh", WELSH }
};
int freerdp_detect_keyboard_layout_from_cf(DWORD* keyboardLayoutId)
{
int i;
CFIndex length;
char* inputSourceId = NULL;
CFStringRef inputSourceIdRef;
TISInputSourceRef inputSrc = TISCopyCurrentKeyboardLayoutInputSource();
if (!inputSrc)
{
DEBUG_KBD("Failed to get current keyboard layout input source!");
return 0;
}
/* get current input source id */
inputSourceIdRef = (CFStringRef)TISGetInputSourceProperty(inputSrc, kTISPropertyInputSourceID);
if (!inputSourceIdRef)
{
DEBUG_KBD("Failed to get input source id!");
goto done;
}
/* convert it to a C-string */
length = CFStringGetLength(inputSourceIdRef);
length = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
inputSourceId = (char*)malloc(length);
if (!inputSourceId)
{
DEBUG_KBD("Failed to allocate string buffer!");
goto done;
}
if (!CFStringGetCString(inputSourceIdRef, inputSourceId, length, kCFStringEncodingUTF8))
{
DEBUG_KBD("Failed to convert CFString to C-string!");
goto done;
}
/* Search for the id in the mapping table */
for (i = 0; i < ARRAYSIZE(KEYBOARD_MAPPING_TABLE); ++i)
{
if (strcmp(inputSourceId, KEYBOARD_MAPPING_TABLE[i].inputSourceId) == 0)
{
*keyboardLayoutId = KEYBOARD_MAPPING_TABLE[i].code;
break;
}
}
done:
free(inputSourceId);
CFRelease(inputSrc);
if (*keyboardLayoutId > 0)
return *keyboardLayoutId;
return 0;
}

View File

@ -0,0 +1,28 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Apple Core Foundation Keyboard Mapping
*
* Copyright 2021 Thincast Technologies GmbH
* Copyright 2021 Martin Fleisz <martin.fleisz@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_LOCALE_KEYBOARD_APPLE_H
#define FREERDP_LOCALE_KEYBOARD_APPLE_H
#include <freerdp/api.h>
FREERDP_LOCAL int freerdp_detect_keyboard_layout_from_cf(DWORD* keyboardLayoutId);
#endif /* FREERDP_LOCALE_KEYBOARD_APPLE_H */

View File

@ -3,6 +3,8 @@
* Microsoft Locales
*
* Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2021 Thincast Technologies GmbH
* Copyright 2021 Martin Fleisz <martin.fleisz@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,22 +23,32 @@
#include "config.h"
#endif
#if defined(__APPLE__)
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFLocale.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <assert.h>
#include <winpr/environment.h>
#include "liblocale.h"
#include <freerdp/locale/locale.h>
#define LOCALE_LANGUAGE_LEN 6
#define LOCALE_COUNTRY_LEN 10
struct _SYSTEM_LOCALE
{
char language[4]; /* Two or three letter language code */
char country[10]; /* Two or three letter country code (Sometimes with Cyrl_ prefix) */
DWORD code; /* 32-bit unsigned integer corresponding to the locale */
char language[LOCALE_LANGUAGE_LEN]; /* Two or three letter language code */
char country[LOCALE_COUNTRY_LEN]; /* Two or three letter country code (Sometimes with Cyrl_
prefix) */
DWORD code; /* 32-bit unsigned integer corresponding to the locale */
};
typedef struct _SYSTEM_LOCALE SYSTEM_LOCALE;
@ -642,77 +654,118 @@ static const LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS_TABLE[] = {
{ XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
};
static BOOL freerdp_get_system_language_and_country_codes(char* language, char* country)
static BOOL freerdp_get_system_language_and_country_codes(char* language, size_t languageLen,
char* country, size_t countryLen)
{
int dot;
DWORD nSize;
int underscore;
char* env_lang = NULL;
LPCSTR lang = "LANG";
/* LANG = <language>_<country>.<encoding> */
nSize = GetEnvironmentVariableA(lang, NULL, 0);
assert(language);
assert(languageLen > 0);
assert(country);
assert(countryLen);
if (!nSize)
return FALSE; /* LANG environment variable was not set */
env_lang = (char*)malloc(nSize);
if (!env_lang)
return FALSE;
if (GetEnvironmentVariableA(lang, env_lang, nSize) !=
nSize - 1) /* Get locale from environment variable LANG */
#if defined(__APPLE__)
{
CFIndex strSize;
CFStringRef langRef, countryRef;
CFLocaleRef localeRef = CFLocaleCopyCurrent();
if (!localeRef)
return FALSE;
langRef = (CFStringRef)CFLocaleGetValue(localeRef, kCFLocaleLanguageCode);
countryRef = (CFStringRef)CFLocaleGetValue(localeRef, kCFLocaleCountryCode);
if (!langRef || !countryRef)
{
CFRelease(localeRef);
return FALSE;
}
if (!CFStringGetCString(langRef, language, languageLen, kCFStringEncodingUTF8) ||
!CFStringGetCString(countryRef, country, countryLen, kCFStringEncodingUTF8))
{
CFRelease(localeRef);
return FALSE;
}
CFRelease(localeRef);
return TRUE;
}
#else
{
int dot;
DWORD nSize;
int underscore;
char* env_lang = NULL;
LPCSTR lang = "LANG";
/* LANG = <language>_<country>.<encoding> */
nSize = GetEnvironmentVariableA(lang, NULL, 0);
if (!nSize)
return FALSE; /* LANG environment variable was not set */
env_lang = (char*)malloc(nSize);
if (!env_lang)
return FALSE;
if (GetEnvironmentVariableA(lang, env_lang, nSize) !=
nSize - 1) /* Get locale from environment variable LANG */
{
free(env_lang);
return FALSE;
}
underscore = strcspn(env_lang, "_");
if (underscore > 3)
{
free(env_lang);
return FALSE; /* The language name should not be more than 3 letters long */
}
else
{
/* Get language code */
size_t len = MIN(languageLen - 1, underscore);
strncpy(language, env_lang, len);
language[len] = '\0';
}
dot = strcspn(env_lang, ".");
/* Get country code */
if (dot > underscore)
{
size_t len = MIN(countryLen - 1, dot - underscore - 1);
strncpy(country, &env_lang[underscore + 1], len);
country[len] = '\0';
}
else
{
free(env_lang);
return FALSE; /* Invalid locale */
}
free(env_lang);
return FALSE;
return TRUE;
}
underscore = strcspn(env_lang, "_");
if (underscore > 3)
{
free(env_lang);
return FALSE; /* The language name should not be more than 3 letters long */
}
else
{
/* Get language code */
strncpy(language, env_lang, underscore);
language[underscore] = '\0';
}
dot = strcspn(env_lang, ".");
/* Get country code */
if (dot > underscore)
{
strncpy(country, &env_lang[underscore + 1], dot - underscore - 1);
country[dot - underscore - 1] = '\0';
}
else
{
free(env_lang);
return FALSE; /* Invalid locale */
}
free(env_lang);
return TRUE;
#endif
}
static SYSTEM_LOCALE* freerdp_detect_system_locale(void)
static const SYSTEM_LOCALE* freerdp_detect_system_locale(void)
{
size_t i;
char language[4];
char country[10];
SYSTEM_LOCALE* locale = NULL;
freerdp_get_system_language_and_country_codes(language, country);
char language[LOCALE_LANGUAGE_LEN] = { 0 };
char country[LOCALE_COUNTRY_LEN] = { 0 };
const SYSTEM_LOCALE* locale = NULL;
freerdp_get_system_language_and_country_codes(language, ARRAYSIZE(language), country,
ARRAYSIZE(country));
for (i = 0; i < ARRAYSIZE(SYSTEM_LOCALE_TABLE); i++)
{
if ((strcmp(language, SYSTEM_LOCALE_TABLE[i].language) == 0) &&
(strcmp(country, SYSTEM_LOCALE_TABLE[i].country) == 0))
const SYSTEM_LOCALE* current = &SYSTEM_LOCALE_TABLE[i];
if ((strcmp(language, current->language) == 0) && (strcmp(country, current->country) == 0))
{
locale = (SYSTEM_LOCALE*)&SYSTEM_LOCALE_TABLE[i];
locale = current;
break;
}
}
@ -722,7 +775,7 @@ static SYSTEM_LOCALE* freerdp_detect_system_locale(void)
DWORD freerdp_get_system_locale_id(void)
{
SYSTEM_LOCALE* locale;
const SYSTEM_LOCALE* locale;
locale = freerdp_detect_system_locale();
if (locale != NULL)
@ -737,8 +790,10 @@ const char* freerdp_get_system_locale_name_from_id(DWORD localeId)
for (index = 0; index < ARRAYSIZE(LOCALE_NAME_TABLE); index++)
{
if (localeId == LOCALE_NAME_TABLE[index].localeId)
return LOCALE_NAME_TABLE[index].name;
const LOCALE_NAME* const current = &LOCALE_NAME_TABLE[index];
if (localeId == current->localeId)
return current->name;
}
return NULL;
@ -747,10 +802,12 @@ const char* freerdp_get_system_locale_name_from_id(DWORD localeId)
int freerdp_detect_keyboard_layout_from_system_locale(DWORD* keyboardLayoutId)
{
size_t i, j;
char language[4];
char country[10];
SYSTEM_LOCALE* locale;
freerdp_get_system_language_and_country_codes(language, country);
char language[LOCALE_LANGUAGE_LEN] = { 0 };
char country[LOCALE_COUNTRY_LEN] = { 0 };
const SYSTEM_LOCALE* locale;
freerdp_get_system_language_and_country_codes(language, ARRAYSIZE(language), country,
ARRAYSIZE(country));
if ((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0))
{
@ -767,22 +824,24 @@ int freerdp_detect_keyboard_layout_from_system_locale(DWORD* keyboardLayoutId)
for (i = 0; i < ARRAYSIZE(LOCALE_KEYBOARD_LAYOUTS_TABLE); i++)
{
if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].locale == locale->code)
const LOCALE_KEYBOARD_LAYOUTS* const current = &LOCALE_KEYBOARD_LAYOUTS_TABLE[i];
if (current->locale == locale->code)
{
/* Locale found in list of default keyboard layouts */
for (j = 0; j < 5; j++)
{
if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES)
if (current->keyboardLayouts[j] == ENGLISH_UNITED_STATES)
{
continue; /* Skip, try to get a more localized keyboard layout */
}
else if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == 0)
else if (current->keyboardLayouts[j] == 0)
{
break; /* No more keyboard layouts */
}
else
{
*keyboardLayoutId = LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j];
*keyboardLayoutId = current->keyboardLayouts[j];
return 0;
}
}

View File

@ -43,6 +43,7 @@ int freerdp_handle_signals(void)
#else
#include <pthread.h>
#include <winpr/debug.h>
volatile sig_atomic_t terminal_needs_reset = 0;
int terminal_fildes = 0;
@ -53,8 +54,15 @@ static void fatal_handler(int signum)
{
struct sigaction default_sigaction;
sigset_t this_mask;
WLog_INFO(TAG, "Caught signal '%s' [%d]", strsignal(signum), signum);
static BOOL recursive = FALSE;
if (!recursive)
{
recursive = TRUE;
WLog_ERR(TAG, "Caught signal '%s' [%d]", strsignal(signum), signum);
winpr_log_backtrace(TAG, WLOG_ERROR, 20);
}
if (terminal_needs_reset)
tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);

View File

@ -51,7 +51,7 @@ if (NOT WIN32)
endif()
# Soname versioning
set(RAW_VERSION_STRING "2.4.1")
set(RAW_VERSION_STRING "2.5.0")
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)

View File

@ -29,9 +29,6 @@
#include <openssl/rc4.h>
#include <openssl/des.h>
#include <openssl/evp.h>
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
#include <openssl/provider.h>
#endif
#endif
#ifdef WITH_MBEDTLS
@ -61,11 +58,6 @@ static WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOO
if (keylen > INT_MAX)
return NULL;
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
if (OSSL_PROVIDER_load(NULL, "legacy") == NULL)
return NULL;
#endif
if (!(ctx = (WINPR_RC4_CTX*)EVP_CIPHER_CTX_new()))
return NULL;

View File

@ -34,18 +34,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <assert.h>
#include "registry_reg.h"
static Reg* instance = NULL;
static Reg* RegGetInstance()
static Reg* RegGetInstance(void)
{
if (!instance)
{
instance = reg_open(1);
}
return instance;
}
@ -213,18 +213,23 @@ LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesir
LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
{
Reg* reg;
RegKey* pKey;
reg = RegGetInstance();
Reg* reg = RegGetInstance();
if (!reg)
return -1;
if (hKey != HKEY_LOCAL_MACHINE)
return ERROR_FILE_NOT_FOUND;
assert(reg->root_key);
pKey = reg->root_key->subkeys;
while (pKey != NULL)
{
if (_stricmp(pKey->subname, lpSubKey) == 0)
assert(lpSubKey);
if (pKey->subname && (_stricmp(pKey->subname, lpSubKey) == 0))
{
*phkResult = (HKEY)pKey;
return ERROR_SUCCESS;
@ -271,24 +276,48 @@ LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD
RegKey* key;
RegVal* pValue;
WINPR_UNUSED(lpReserved);
key = (RegKey*)hKey;
assert(key);
pValue = key->values;
while (pValue != NULL)
{
if (strcmp(pValue->name, lpValueName) == 0)
{
if (lpType)
*lpType = pValue->type;
if (pValue->type == REG_DWORD)
{
DWORD* pData = (DWORD*)lpData;
if (pData != NULL)
if (lpcbData)
{
*pData = pValue->data.dword;
DWORD size = *lpcbData;
*lpcbData = sizeof(DWORD);
if (pData)
{
if (size < *lpcbData)
return ERROR_MORE_DATA;
}
}
*lpcbData = sizeof(DWORD);
if (pData != NULL)
{
DWORD size;
assert(lpcbData);
size = *lpcbData;
*lpcbData = sizeof(DWORD);
if (size < sizeof(DWORD))
return ERROR_MORE_DATA;
*pData = pValue->data.dword;
}
else if (lpcbData != NULL)
*lpcbData = sizeof(DWORD);
return ERROR_SUCCESS;
}
else if (pValue->type == REG_SZ)
@ -300,11 +329,18 @@ LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD
if (pData != NULL)
{
DWORD size;
assert(lpcbData);
size = *lpcbData;
*lpcbData = length;
if (size < length)
return ERROR_MORE_DATA;
memcpy(pData, pValue->data.string, length);
pData[length] = '\0';
}
*lpcbData = (UINT32)length;
else if (lpcbData)
*lpcbData = (UINT32)length;
return ERROR_SUCCESS;
}

View File

@ -27,6 +27,7 @@
#include <string.h>
#include <winpr/wtypes.h>
#include <assert.h>
#include <winpr/crt.h>
#include <winpr/file.h>
@ -35,12 +36,14 @@
#include "../log.h"
#define TAG WINPR_TAG("registry")
#define WINPR_ASSERT assert
#define WINPR_HKLM_HIVE "/etc/winpr/HKLM.reg"
struct reg_data_type
{
char* tag;
int length;
size_t length;
DWORD type;
};
@ -52,50 +55,71 @@ static struct reg_data_type REG_DATA_TYPE_TABLE[] = { { "\"", 1, REG_SZ },
{ "hex:", 4, REG_BINARY },
{ "hex(2):\"", 8, REG_EXPAND_SZ },
{ "hex(7):\"", 8, REG_MULTI_SZ },
{ "hex(b):\"", 8, REG_QWORD },
{ NULL, 0, 0 } };
{ "hex(b):\"", 8, REG_QWORD } };
static char* REG_DATA_TYPE_STRINGS[] = { "REG_NONE",
"REG_SZ",
"REG_EXPAND_SZ",
"REG_BINARY",
"REG_DWORD",
"REG_DWORD_BIG_ENDIAN",
"REG_LINK",
"REG_MULTI_SZ",
"REG_RESOURCE_LIST",
"REG_FULL_RESOURCE_DESCRIPTOR",
"REG_RESOURCE_REQUIREMENTS_LIST",
"REG_QWORD" };
static void reg_load_start(Reg* reg)
static char* reg_data_type_string(DWORD type)
{
switch (type)
{
case REG_NONE:
return "REG_NONE";
case REG_SZ:
return "REG_SZ";
case REG_EXPAND_SZ:
return "REG_EXPAND_SZ";
case REG_BINARY:
return "REG_BINARY";
case REG_DWORD:
return "REG_DWORD";
case REG_DWORD_BIG_ENDIAN:
return "REG_DWORD_BIG_ENDIAN";
case REG_LINK:
return "REG_LINK";
case REG_MULTI_SZ:
return "REG_MULTI_SZ";
case REG_RESOURCE_LIST:
return "REG_RESOURCE_LIST";
case REG_FULL_RESOURCE_DESCRIPTOR:
return "REG_FULL_RESOURCE_DESCRIPTOR";
case REG_RESOURCE_REQUIREMENTS_LIST:
return "REG_RESOURCE_REQUIREMENTS_LIST";
case REG_QWORD:
return "REG_QWORD";
default:
return "REG_UNKNOWN";
}
}
static BOOL reg_load_start(Reg* reg)
{
char* buffer;
INT64 file_size;
WINPR_ASSERT(reg);
WINPR_ASSERT(reg->fp);
_fseeki64(reg->fp, 0, SEEK_END);
file_size = _ftelli64(reg->fp);
_fseeki64(reg->fp, 0, SEEK_SET);
reg->line = NULL;
reg->next_line = NULL;
reg->buffer = NULL;
if (file_size < 1)
return;
return FALSE;
reg->buffer = (char*)malloc(file_size + 2);
buffer = (char*)realloc(reg->buffer, (size_t)file_size + 2);
if (!reg->buffer)
return;
if (!buffer)
return FALSE;
reg->buffer = buffer;
if (fread(reg->buffer, file_size, 1, reg->fp) != 1)
{
free(reg->buffer);
reg->buffer = NULL;
return;
}
if (fread(reg->buffer, (size_t)file_size, 1, reg->fp) != 1)
return FALSE;
reg->buffer[file_size] = '\n';
reg->buffer[file_size + 1] = '\0';
reg->next_line = strtok(reg->buffer, "\n");
return TRUE;
}
static void reg_load_finish(Reg* reg)
@ -112,15 +136,23 @@ static void reg_load_finish(Reg* reg)
static RegVal* reg_load_value(Reg* reg, RegKey* key)
{
int index;
char* p[5];
int length;
char* name;
size_t index;
char* p[5] = { 0 };
size_t length;
char* name = NULL;
char* type;
char* data;
RegVal* value;
RegVal* value = NULL;
WINPR_ASSERT(reg);
WINPR_ASSERT(key);
WINPR_ASSERT(reg->line);
p[0] = reg->line + 1;
p[1] = strstr(p[0], "\"=");
if (!p[1])
return NULL;
p[2] = p[1] + 2;
type = p[2];
@ -129,67 +161,85 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key)
else
p[3] = strchr(p[2], ':');
if (!p[3])
return NULL;
data = p[3] + 1;
length = p[1] - p[0];
name = (char*)malloc(length + 1);
length = (size_t)(p[1] - p[0]);
if (length < 1)
goto fail;
name = (char*)calloc(length + 1, sizeof(char));
if (!name)
return NULL;
goto fail;
memcpy(name, p[0], length);
name[length] = '\0';
value = (RegVal*)malloc(sizeof(RegVal));
value = (RegVal*)calloc(1, sizeof(RegVal));
if (!value)
{
free(name);
return NULL;
}
goto fail;
value->name = name;
value->type = REG_NONE;
value->next = value->prev = NULL;
for (index = 0; REG_DATA_TYPE_TABLE[index].length > 0; index++)
for (index = 0; index < ARRAYSIZE(REG_DATA_TYPE_TABLE); index++)
{
if (strncmp(type, REG_DATA_TYPE_TABLE[index].tag, REG_DATA_TYPE_TABLE[index].length) == 0)
const struct reg_data_type* current = &REG_DATA_TYPE_TABLE[index];
WINPR_ASSERT(current->tag);
WINPR_ASSERT(current->length > 0);
WINPR_ASSERT(current->type != REG_NONE);
if (strncmp(type, current->tag, current->length) == 0)
{
value->type = REG_DATA_TYPE_TABLE[index].type;
value->type = current->type;
break;
}
}
if (value->type == REG_DWORD)
switch (value->type)
{
unsigned long val;
errno = 0;
val = strtoul(data, NULL, 16);
if ((errno != 0) || (val > UINT32_MAX))
case REG_DWORD:
{
free(value);
free(name);
return NULL;
unsigned long val;
errno = 0;
val = strtoul(data, NULL, 16);
if ((errno != 0) || (val > UINT32_MAX))
goto fail;
value->data.dword = (DWORD)val;
}
value->data.dword = val;
}
else if (value->type == REG_SZ)
{
p[4] = strchr(data, '"');
p[4][0] = '\0';
value->data.string = _strdup(data);
if (!value->data.string)
break;
case REG_SZ:
{
free(value);
free(name);
return NULL;
size_t len, cmp;
char* end;
char* start = strchr(data, '"');
if (!start)
goto fail;
/* Check for terminating quote, check it is the last symbol */
len = strlen(start);
end = strchr(start + 1, '"');
if (!end)
goto fail;
cmp = end - start + 1;
if (len != cmp)
goto fail;
if (start[0] == '"')
start++;
if (end[0] == '"')
end[0] = '\0';
value->data.string = _strdup(start);
if (!value->data.string)
goto fail;
}
}
else
{
WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
break;
default:
WLog_ERR(TAG, "unimplemented format: %s", reg_data_type_string(value->type));
break;
}
if (!key->values)
@ -210,6 +260,11 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key)
}
return value;
fail:
free(value);
free(name);
return NULL;
}
static BOOL reg_load_has_next_line(Reg* reg)
@ -233,15 +288,21 @@ static char* reg_load_get_next_line(Reg* reg)
static char* reg_load_peek_next_line(Reg* reg)
{
WINPR_ASSERT(reg);
return reg->next_line;
}
static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey)
{
char* name;
char* path;
char* save;
int length;
char* name = NULL;
char* path = NULL;
char* save = NULL;
WINPR_ASSERT(reg);
WINPR_ASSERT(key);
WINPR_ASSERT(subkey);
WINPR_ASSERT(subkey->name);
path = _strdup(subkey->name);
if (!path)
@ -253,9 +314,8 @@ static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey)
{
if (strcmp(key->name, name) == 0)
{
length = strlen(name);
name += length + 1;
subkey->subname = _strdup(name);
if (save)
subkey->subname = _strdup(save);
/* TODO: free allocated memory in error case */
if (!subkey->subname)
@ -274,19 +334,24 @@ static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey)
static RegKey* reg_load_key(Reg* reg, RegKey* key)
{
char* p[2];
int length;
char* line;
size_t length;
RegKey* subkey;
WINPR_ASSERT(reg);
WINPR_ASSERT(key);
WINPR_ASSERT(reg->line);
p[0] = reg->line + 1;
p[1] = strrchr(p[0], ']');
subkey = (RegKey*)malloc(sizeof(RegKey));
if (!p[1])
return NULL;
subkey = (RegKey*)calloc(1, sizeof(RegKey));
if (!subkey)
return NULL;
subkey->values = NULL;
subkey->prev = subkey->next = NULL;
length = p[1] - p[0];
length = (size_t)(p[1] - p[0]);
subkey->name = (char*)malloc(length + 1);
if (!subkey->name)
@ -300,7 +365,7 @@ static RegKey* reg_load_key(Reg* reg, RegKey* key)
while (reg_load_has_next_line(reg))
{
line = reg_load_peek_next_line(reg);
char* line = reg_load_peek_next_line(reg);
if (line[0] == '[')
break;
@ -354,16 +419,16 @@ static void reg_load(Reg* reg)
static void reg_unload_value(Reg* reg, RegVal* value)
{
if (value->type == REG_DWORD)
WINPR_ASSERT(reg);
WINPR_ASSERT(value);
switch (value->type)
{
}
else if (value->type == REG_SZ)
{
free(value->data.string);
}
else
{
WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
case REG_SZ:
free(value->data.string);
break;
default:
break;
}
free(value);
@ -372,12 +437,15 @@ static void reg_unload_value(Reg* reg, RegVal* value)
static void reg_unload_key(Reg* reg, RegKey* key)
{
RegVal* pValue;
RegVal* pValueNext;
WINPR_ASSERT(reg);
WINPR_ASSERT(key);
pValue = key->values;
while (pValue != NULL)
{
pValueNext = pValue->next;
RegVal* pValueNext = pValue->next;
reg_unload_value(reg, pValue);
pValue = pValueNext;
}
@ -389,23 +457,26 @@ static void reg_unload_key(Reg* reg, RegKey* key)
static void reg_unload(Reg* reg)
{
RegKey* pKey;
RegKey* pKeyNext;
pKey = reg->root_key->subkeys;
while (pKey != NULL)
WINPR_ASSERT(reg);
if (reg->root_key)
{
pKeyNext = pKey->next;
reg_unload_key(reg, pKey);
pKey = pKeyNext;
}
pKey = reg->root_key->subkeys;
free(reg->root_key);
while (pKey != NULL)
{
RegKey* pKeyNext = pKey->next;
reg_unload_key(reg, pKey);
pKey = pKeyNext;
}
free(reg->root_key);
}
}
Reg* reg_open(BOOL read_only)
{
Reg* reg;
reg = (Reg*)malloc(sizeof(Reg));
Reg* reg = (Reg*)calloc(1, sizeof(Reg));
if (!reg)
return NULL;
@ -414,9 +485,7 @@ Reg* reg_open(BOOL read_only)
reg->filename = WINPR_HKLM_HIVE;
if (reg->read_only)
{
reg->fp = winpr_fopen(reg->filename, "r");
}
else
{
reg->fp = winpr_fopen(reg->filename, "r+");
@ -426,25 +495,22 @@ Reg* reg_open(BOOL read_only)
}
if (!reg->fp)
{
free(reg);
return NULL;
}
goto fail;
reg->root_key = (RegKey*)malloc(sizeof(RegKey));
reg->root_key = (RegKey*)calloc(1, sizeof(RegKey));
if (!reg->root_key)
{
fclose(reg->fp);
free(reg);
return NULL;
}
goto fail;
reg->root_key->values = NULL;
reg->root_key->subkeys = NULL;
reg->root_key->name = "HKEY_LOCAL_MACHINE";
reg_load(reg);
return reg;
fail:
reg_close(reg);
return NULL;
}
void reg_close(Reg* reg)
@ -452,7 +518,8 @@ void reg_close(Reg* reg)
if (reg)
{
reg_unload(reg);
fclose(reg->fp);
if (reg->fp)
fclose(reg->fp);
free(reg);
}
}

View File

@ -30,7 +30,7 @@ struct _reg
FILE* fp;
char* line;
char* next_line;
int line_length;
size_t line_length;
char* buffer;
char* filename;
BOOL read_only;
@ -44,7 +44,8 @@ struct _reg_val
RegVal* prev;
RegVal* next;
union reg_data {
union reg_data
{
DWORD dword;
char* string;
} data;

View File

@ -33,6 +33,10 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
#include <openssl/provider.h>
#endif
#include "../log.h"
#define TAG WINPR_TAG("utils.ssl")
@ -242,9 +246,10 @@ static BOOL winpr_enable_fips(DWORD flags)
WLog_ERR(TAG, "Openssl fips mode not available on openssl versions less than 1.0.1!");
return FALSE;
#else
WLog_DBG(TAG, "Ensuring openssl fips mode is ENabled");
WLog_DBG(TAG, "Ensuring openssl fips mode is enabled");
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
OSSL_PROVIDER_load(NULL, "fips");
if (!EVP_default_properties_is_fips_enabled(NULL))
#else
if (FIPS_mode() != 1)
@ -255,10 +260,10 @@ static BOOL winpr_enable_fips(DWORD flags)
#else
if (FIPS_mode_set(1))
#endif
WLog_INFO(TAG, "Openssl fips mode ENabled!");
WLog_INFO(TAG, "Openssl fips mode enabled!");
else
{
WLog_ERR(TAG, "Openssl fips mode ENable failed!");
WLog_ERR(TAG, "Openssl fips mode enable failed!");
return FALSE;
}
}
@ -305,8 +310,15 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
return FALSE;
#endif
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
/* The legacy provider is needed for MD4. */
OSSL_PROVIDER_load(NULL, "legacy");
OSSL_PROVIDER_load(NULL, "default");
#endif
g_winpr_openssl_initialized_by_winpr = TRUE;
return winpr_enable_fips(flags);
return TRUE;
}
/* exported functions */