New upstream version 2.9.0+dfsg1
This commit is contained in:
parent
03a18ec27e
commit
97496cbb22
@ -85,7 +85,7 @@ if ($ENV{BUILD_NUMBER})
|
||||
endif()
|
||||
set(WITH_LIBRARY_VERSIONING "ON")
|
||||
|
||||
set(RAW_VERSION_STRING "2.8.1")
|
||||
set(RAW_VERSION_STRING "2.9.0")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
||||
elseif(USE_VERSION_FROM_GIT_TAG)
|
||||
|
||||
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
||||
# 2022-11-16 Version 2.9.0
|
||||
|
||||
Notewhorth changes:
|
||||
* Backported #8252: Support sending server redirection PDU
|
||||
* Backported #8406: Ensure X11 client cursor is never smaller 1x1
|
||||
* Backported #8403: Fixed multiple client side input validation issues
|
||||
(CVE-2022-39316, CVE-2022-39317, CVE-2022-39318, CVE-2022-39319,
|
||||
CVE-2022-39320, CVE-2022-41877, CVE-2022-39347)
|
||||
* Backported #7282: Proxy server now discards input events sent before
|
||||
activation was received
|
||||
* Backported #8324: Internal replacements for md4, md5 and hmac-md5
|
||||
For the time being the RDP protocol requires these outdated hash
|
||||
algorithms. So any distribution that wants to ship a working
|
||||
FreeRDP should check the options WITH_INTERNAL_MD4 (and depending
|
||||
on OpenSSL deprecation status WITH_INTERNAL_MD5)
|
||||
|
||||
Fixed issues:
|
||||
* Backported #8341: Null checks in winpr_Digest_Free
|
||||
* Backported #8335: Missing NULL return in winpr_Digest_New
|
||||
* Backported #8192: Support for audin version 2 microphone channel
|
||||
* Backported #7282: Discard input events before activation (Fixes #8374)
|
||||
|
||||
For a complete and detailed change log since the last release run:
|
||||
git log 2.8.1..2.9.0
|
||||
|
||||
|
||||
# 2022-10-12 Version 2.8.1
|
||||
|
||||
Notewhorth changes:
|
||||
|
||||
@ -43,13 +43,18 @@
|
||||
|
||||
#include "audin_main.h"
|
||||
|
||||
#define MSG_SNDIN_VERSION 0x01
|
||||
#define MSG_SNDIN_FORMATS 0x02
|
||||
#define MSG_SNDIN_OPEN 0x03
|
||||
#define MSG_SNDIN_OPEN_REPLY 0x04
|
||||
#define MSG_SNDIN_DATA_INCOMING 0x05
|
||||
#define MSG_SNDIN_DATA 0x06
|
||||
#define MSG_SNDIN_FORMATCHANGE 0x07
|
||||
#define SNDIN_VERSION 0x02
|
||||
|
||||
enum
|
||||
{
|
||||
MSG_SNDIN_VERSION = 0x01,
|
||||
MSG_SNDIN_FORMATS = 0x02,
|
||||
MSG_SNDIN_OPEN = 0x03,
|
||||
MSG_SNDIN_OPEN_REPLY = 0x04,
|
||||
MSG_SNDIN_DATA_INCOMING = 0x05,
|
||||
MSG_SNDIN_DATA = 0x06,
|
||||
MSG_SNDIN_FORMATCHANGE = 0x07
|
||||
} MSG_SNDIN_CMD;
|
||||
|
||||
typedef struct _AUDIN_LISTENER_CALLBACK AUDIN_LISTENER_CALLBACK;
|
||||
struct _AUDIN_LISTENER_CALLBACK
|
||||
@ -105,6 +110,7 @@ struct _AUDIN_PLUGIN
|
||||
IWTSListener* listener;
|
||||
|
||||
BOOL initialized;
|
||||
UINT32 version;
|
||||
};
|
||||
|
||||
static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args);
|
||||
@ -138,7 +144,7 @@ static UINT audin_channel_write_and_free(AUDIN_CHANNEL_CALLBACK* callback, wStre
|
||||
static UINT audin_process_version(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
wStream* out;
|
||||
const UINT32 ClientVersion = 0x01;
|
||||
const UINT32 ClientVersion = SNDIN_VERSION;
|
||||
UINT32 ServerVersion;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
@ -149,7 +155,7 @@ static UINT audin_process_version(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
|
||||
ServerVersion, ClientVersion);
|
||||
|
||||
/* Do not answer server packet, we do not support the channel version. */
|
||||
if (ServerVersion != ClientVersion)
|
||||
if (ServerVersion > ClientVersion)
|
||||
{
|
||||
WLog_Print(audin->log, WLOG_WARN,
|
||||
"Incompatible channel version server=%" PRIu32
|
||||
@ -157,6 +163,7 @@ static UINT audin_process_version(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
|
||||
ServerVersion, ClientVersion);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
audin->version = ServerVersion;
|
||||
|
||||
out = Stream_New(NULL, 5);
|
||||
|
||||
|
||||
@ -61,10 +61,14 @@
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static void drive_file_fix_path(WCHAR* path)
|
||||
static BOOL drive_file_fix_path(WCHAR* path, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
size_t length = _wcslen(path);
|
||||
|
||||
if ((length == 0) || (length > UINT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(path);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@ -75,58 +79,82 @@ static void drive_file_fix_path(WCHAR* path)
|
||||
#ifdef WIN32
|
||||
|
||||
if ((length == 3) && (path[1] == L':') && (path[2] == L'/'))
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
if ((length == 1) && (path[0] == L'/'))
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
if ((length > 0) && (path[length - 1] == L'/'))
|
||||
path[length - 1] = L'\0';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static WCHAR* drive_file_combine_fullpath(const WCHAR* base_path, const WCHAR* path,
|
||||
size_t PathLength)
|
||||
size_t PathWCharLength)
|
||||
{
|
||||
WCHAR* fullpath;
|
||||
size_t base_path_length;
|
||||
BOOL ok = FALSE;
|
||||
WCHAR* fullpath = NULL;
|
||||
size_t length;
|
||||
|
||||
if (!base_path || (!path && (PathLength > 0)))
|
||||
return NULL;
|
||||
if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
goto fail;
|
||||
|
||||
base_path_length = _wcslen(base_path) * 2;
|
||||
fullpath = (WCHAR*)calloc(1, base_path_length + PathLength + sizeof(WCHAR));
|
||||
const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
|
||||
length = base_path_length + PathWCharLength + 1;
|
||||
fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
goto fail;
|
||||
|
||||
CopyMemory(fullpath, base_path, base_path_length * sizeof(WCHAR));
|
||||
if (path)
|
||||
CopyMemory(&fullpath[base_path_length], path, PathWCharLength * sizeof(WCHAR));
|
||||
|
||||
if (!drive_file_fix_path(fullpath, length))
|
||||
goto fail;
|
||||
|
||||
/* Ensure the path does not contain sequences like '..' */
|
||||
const WCHAR dotdot[] = { '.', '.', '\0' };
|
||||
if (_wcsstr(&fullpath[base_path_length], dotdot))
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return NULL;
|
||||
char abuffer[MAX_PATH] = { 0 };
|
||||
ConvertFromUnicode(CP_UTF8, 0, &fullpath[base_path_length], -1, (char**)&abuffer,
|
||||
ARRAYSIZE(abuffer) - 1, NULL, NULL);
|
||||
|
||||
WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from server, aborting!",
|
||||
&abuffer[base_path_length]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
CopyMemory(fullpath, base_path, base_path_length);
|
||||
if (path)
|
||||
CopyMemory((char*)fullpath + base_path_length, path, PathLength);
|
||||
drive_file_fix_path(fullpath);
|
||||
ok = TRUE;
|
||||
fail:
|
||||
if (!ok)
|
||||
{
|
||||
free(fullpath);
|
||||
fullpath = NULL;
|
||||
}
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
{
|
||||
WIN32_FIND_DATAW findFileData;
|
||||
WIN32_FIND_DATAW findFileData = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
HANDLE dir;
|
||||
WCHAR* fullpath;
|
||||
WCHAR* path_slash;
|
||||
size_t base_path_length;
|
||||
HANDLE dir = INVALID_HANDLE_VALUE;
|
||||
WCHAR* fullpath = NULL;
|
||||
WCHAR* path_slash = NULL;
|
||||
size_t base_path_length = 0;
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
base_path_length = _wcslen(path) * 2;
|
||||
path_slash = (WCHAR*)calloc(1, base_path_length + sizeof(WCHAR) * 3);
|
||||
base_path_length = _wcslen(path);
|
||||
path_slash = (WCHAR*)calloc(base_path_length + 3, sizeof(WCHAR));
|
||||
|
||||
if (!path_slash)
|
||||
{
|
||||
@ -134,12 +162,11 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CopyMemory(path_slash, path, base_path_length);
|
||||
path_slash[base_path_length / 2] = L'/';
|
||||
path_slash[base_path_length / 2 + 1] = L'*';
|
||||
CopyMemory(path_slash, path, base_path_length * sizeof(WCHAR));
|
||||
path_slash[base_path_length] = L'/';
|
||||
path_slash[base_path_length + 1] = L'*';
|
||||
DEBUG_WSTR("Search in %s", path_slash);
|
||||
dir = FindFirstFileW(path_slash, &findFileData);
|
||||
path_slash[base_path_length / 2 + 1] = 0;
|
||||
|
||||
if (dir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@ -149,7 +176,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
|
||||
do
|
||||
{
|
||||
size_t len = _wcslen(findFileData.cFileName);
|
||||
const size_t len = _wcsnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
|
||||
|
||||
if ((len == 1 && findFileData.cFileName[0] == L'.') ||
|
||||
(len == 2 && findFileData.cFileName[0] == L'.' && findFileData.cFileName[1] == L'.'))
|
||||
@ -157,7 +184,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
continue;
|
||||
}
|
||||
|
||||
fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len * 2);
|
||||
fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len);
|
||||
DEBUG_WSTR("Delete %s", fullpath);
|
||||
|
||||
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
@ -333,13 +360,13 @@ static BOOL drive_file_init(DRIVE_FILE* file)
|
||||
return file->file_handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
|
||||
if (!base_path || (!path && (PathLength > 0)))
|
||||
if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
return NULL;
|
||||
|
||||
file = (DRIVE_FILE*)calloc(1, sizeof(DRIVE_FILE));
|
||||
@ -359,7 +386,7 @@ DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 Pat
|
||||
file->CreateDisposition = CreateDisposition;
|
||||
file->CreateOptions = CreateOptions;
|
||||
file->SharedAccess = SharedAccess;
|
||||
drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathLength));
|
||||
drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathWCharLength));
|
||||
|
||||
if (!drive_file_init(file))
|
||||
{
|
||||
@ -714,13 +741,10 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
return FALSE;
|
||||
|
||||
fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input),
|
||||
FileNameLength);
|
||||
FileNameLength / sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
{
|
||||
WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@ -759,7 +783,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
}
|
||||
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
const WCHAR* path, UINT32 PathLength, wStream* output)
|
||||
const WCHAR* path, UINT32 PathWCharLength, wStream* output)
|
||||
{
|
||||
size_t length;
|
||||
WCHAR* ent_path;
|
||||
@ -773,7 +797,7 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
if (file->find_handle != INVALID_HANDLE_VALUE)
|
||||
FindClose(file->find_handle);
|
||||
|
||||
ent_path = drive_file_combine_fullpath(file->basepath, path, PathLength);
|
||||
ent_path = drive_file_combine_fullpath(file->basepath, path, PathWCharLength);
|
||||
/* open new search handle and retrieve the first entry */
|
||||
file->find_handle = FindFirstFileW(ent_path, &file->find_data);
|
||||
free(ent_path);
|
||||
|
||||
@ -51,9 +51,9 @@ struct _DRIVE_FILE
|
||||
UINT32 CreateOptions;
|
||||
};
|
||||
|
||||
DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
BOOL drive_file_free(DRIVE_FILE* file);
|
||||
|
||||
BOOL drive_file_open(DRIVE_FILE* file);
|
||||
@ -64,6 +64,6 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||
wStream* input);
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
const WCHAR* path, UINT32 PathLength, wStream* output);
|
||||
const WCHAR* path, UINT32 PathWCharLength, wStream* output);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
||||
|
||||
@ -184,8 +184,8 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
|
||||
|
||||
path = (const WCHAR*)Stream_Pointer(irp->input);
|
||||
FileId = irp->devman->id_sequence++;
|
||||
file = drive_file_new(drive->path, path, PathLength, FileId, DesiredAccess, CreateDisposition,
|
||||
CreateOptions, FileAttributes, SharedAccess);
|
||||
file = drive_file_new(drive->path, path, PathLength / sizeof(WCHAR), FileId, DesiredAccess,
|
||||
CreateDisposition, CreateOptions, FileAttributes, SharedAccess);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
@ -629,6 +629,9 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||
Stream_Read_UINT32(irp->input, PathLength);
|
||||
Stream_Seek(irp->input, 23); /* Padding */
|
||||
path = (WCHAR*)Stream_Pointer(irp->input);
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, PathLength))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
@ -636,8 +639,8 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Stream_Write_UINT32(irp->output, 0); /* Length */
|
||||
}
|
||||
else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, PathLength,
|
||||
irp->output))
|
||||
else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path,
|
||||
PathLength / sizeof(WCHAR), irp->output))
|
||||
{
|
||||
irp->IoStatus = drive_map_windows_err(GetLastError());
|
||||
}
|
||||
|
||||
@ -97,7 +97,13 @@ static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId,
|
||||
UINT32 OutputBufferSize)
|
||||
{
|
||||
const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
|
||||
wStream* out = Stream_New(NULL, OutputBufferSize + 28);
|
||||
|
||||
#if UINT32_MAX >= SIZE_MAX
|
||||
if (OutputBufferSize > UINT32_MAX - 28ull)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
wStream* out = Stream_New(NULL, OutputBufferSize + 28ull);
|
||||
|
||||
if (!out)
|
||||
return NULL;
|
||||
@ -241,6 +247,10 @@ static UINT urbdrc_process_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* c
|
||||
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
Stream_Read_UINT32(s, RequestId);
|
||||
|
||||
if (OutputBufferSize > UINT32_MAX - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
|
||||
out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
|
||||
|
||||
@ -673,7 +683,11 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba
|
||||
buffer = Stream_Pointer(out);
|
||||
|
||||
if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
{
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
return ERROR_INVALID_DATA;
|
||||
Stream_Copy(s, out, OutputBufferSize);
|
||||
}
|
||||
|
||||
/** process TS_URB_CONTROL_TRANSFER */
|
||||
if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
|
||||
@ -720,6 +734,15 @@ static UINT urb_bulk_or_interrupt_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA
|
||||
Stream_Read_UINT32(s, TransferFlags); /** TransferFlags */
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
EndpointAddress = (PipeHandle & 0x000000ff);
|
||||
|
||||
if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
{
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
{
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/** process TS_URB_BULK_OR_INTERRUPT_TRANSFER */
|
||||
return pdev->bulk_or_interrupt_transfer(
|
||||
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, noAck,
|
||||
@ -804,6 +827,13 @@ static UINT urb_isoch_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback
|
||||
packetDescriptorData = Stream_Pointer(s);
|
||||
Stream_Seek(s, NumberOfPackets * 12);
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
|
||||
if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
{
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
return pdev->isoch_transfer(
|
||||
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
|
||||
ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
|
||||
|
||||
@ -1221,12 +1221,18 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, URBDRC_CHANNEL_CALLBACK* c
|
||||
if (!Buffer)
|
||||
Stream_Seek(user_data->data, (NumberOfPackets * 12));
|
||||
|
||||
iso_packet_size = BufferSize / NumberOfPackets;
|
||||
iso_transfer = libusb_alloc_transfer(NumberOfPackets);
|
||||
if (NumberOfPackets > 0)
|
||||
{
|
||||
iso_packet_size = BufferSize / NumberOfPackets;
|
||||
iso_transfer = libusb_alloc_transfer((int)NumberOfPackets);
|
||||
}
|
||||
|
||||
if (iso_transfer == NULL)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_ERROR, "Error: libusb_alloc_transfer.");
|
||||
WLog_Print(urbdrc->log, WLOG_ERROR,
|
||||
"Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
|
||||
" ]",
|
||||
NumberOfPackets, BufferSize);
|
||||
async_transfer_user_data_free(user_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -258,8 +258,8 @@ static BOOL xf_Pointer_GetCursorForCurrentScale(rdpContext* context, const rdpPo
|
||||
|
||||
xscale = (settings->SmartSizing ? xfc->scaledWidth / (double)settings->DesktopWidth : 1);
|
||||
yscale = (settings->SmartSizing ? xfc->scaledHeight / (double)settings->DesktopHeight : 1);
|
||||
xTargetSize = pointer->width * xscale;
|
||||
yTargetSize = pointer->height * yscale;
|
||||
xTargetSize = MAX(1, pointer->width * xscale);
|
||||
yTargetSize = MAX(1, pointer->height * yscale);
|
||||
|
||||
WLog_DBG(TAG, "%s: scaled: %" PRIu32 "x%" PRIu32 ", desktop: %" PRIu32 "x%" PRIu32, __func__,
|
||||
xfc->scaledWidth, xfc->savedHeight, settings->DesktopWidth, settings->DesktopHeight);
|
||||
|
||||
@ -183,4 +183,7 @@
|
||||
/* Proxy */
|
||||
#cmakedefine WITH_PROXY_MODULES
|
||||
|
||||
#cmakedefine WITH_INTERNAL_MD4
|
||||
#cmakedefine WITH_INTERNAL_MD5
|
||||
|
||||
#endif /* FREERDP_CONFIG_H */
|
||||
|
||||
@ -70,6 +70,25 @@ extern "C"
|
||||
#define VERIFY_CERT_FLAG_MISMATCH 0x80
|
||||
#define VERIFY_CERT_FLAG_MATCH_LEGACY_SHA1 0x100
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CONNECTION_STATE_INITIAL,
|
||||
CONNECTION_STATE_NEGO,
|
||||
CONNECTION_STATE_NLA,
|
||||
CONNECTION_STATE_MCS_CONNECT,
|
||||
CONNECTION_STATE_MCS_ERECT_DOMAIN,
|
||||
CONNECTION_STATE_MCS_ATTACH_USER,
|
||||
CONNECTION_STATE_MCS_CHANNEL_JOIN,
|
||||
CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT,
|
||||
CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE,
|
||||
CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT,
|
||||
CONNECTION_STATE_LICENSING,
|
||||
CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING,
|
||||
CONNECTION_STATE_CAPABILITIES_EXCHANGE,
|
||||
CONNECTION_STATE_FINALIZATION,
|
||||
CONNECTION_STATE_ACTIVE
|
||||
} CONNECTION_STATE;
|
||||
|
||||
/* Message types used by gateway messaging callback */
|
||||
#define GATEWAY_MESSAGE_CONSENT 1
|
||||
#define GATEWAY_MESSAGE_SERVICE 2
|
||||
@ -527,6 +546,9 @@ extern "C"
|
||||
|
||||
FREERDP_API const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length);
|
||||
|
||||
FREERDP_API CONNECTION_STATE freerdp_get_state(rdpContext* context);
|
||||
FREERDP_API const char* freerdp_state_string(CONNECTION_STATE state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -48,6 +48,13 @@ typedef BOOL (*psPeerCapabilities)(freerdp_peer* peer);
|
||||
typedef BOOL (*psPeerPostConnect)(freerdp_peer* peer);
|
||||
typedef BOOL (*psPeerActivate)(freerdp_peer* peer);
|
||||
typedef BOOL (*psPeerLogon)(freerdp_peer* peer, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic);
|
||||
typedef BOOL (*psPeerSendServerRedirection)(freerdp_peer* peer, UINT32 sessionId,
|
||||
const char* targetNetAddress, const char* routingToken,
|
||||
const char* userName, const char* domain,
|
||||
const char* password, const char* targetFQDN,
|
||||
const char* targetNetBiosName, DWORD tsvUrlLength,
|
||||
const BYTE* tsvUrl, UINT32 targetNetAddressesCount,
|
||||
const char** targetNetAddresses);
|
||||
typedef BOOL (*psPeerAdjustMonitorsLayout)(freerdp_peer* peer);
|
||||
typedef BOOL (*psPeerClientCapabilities)(freerdp_peer* peer);
|
||||
|
||||
@ -133,6 +140,8 @@ struct rdp_freerdp_peer
|
||||
psPeerClientCapabilities ClientCapabilities;
|
||||
psPeerComputeNtlmHash ComputeNtlmHash;
|
||||
psPeerLicenseCallback LicenseCallback;
|
||||
|
||||
psPeerSendServerRedirection SendServerRedirection;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -230,19 +230,19 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
BYTE* pbSegment;
|
||||
size_t cbSegment;
|
||||
|
||||
if (!zgfx || !stream)
|
||||
if (!zgfx || !stream || (segmentSize < 2))
|
||||
return FALSE;
|
||||
|
||||
cbSegment = segmentSize - 1;
|
||||
|
||||
if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) ||
|
||||
(segmentSize > UINT32_MAX))
|
||||
if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize > UINT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(stream, flags); /* header (1 byte) */
|
||||
zgfx->OutputCount = 0;
|
||||
pbSegment = Stream_Pointer(stream);
|
||||
Stream_Seek(stream, cbSegment);
|
||||
if (!Stream_SafeSeek(stream, cbSegment))
|
||||
return FALSE;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
@ -346,6 +346,9 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
||||
return FALSE;
|
||||
|
||||
if (count > zgfx->cBitsRemaining / 8)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
||||
count);
|
||||
zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count);
|
||||
|
||||
@ -350,7 +350,7 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
|
||||
UINT16 lengthSourceDescriptor;
|
||||
UINT32 timeout;
|
||||
|
||||
if (rdp->state == CONNECTION_STATE_ACTIVE)
|
||||
if (rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE)
|
||||
rdp->deactivation_reactivation = TRUE;
|
||||
else
|
||||
rdp->deactivation_reactivation = FALSE;
|
||||
@ -390,7 +390,7 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
|
||||
if (freerdp_shall_disconnect(rdp->instance))
|
||||
return TRUE;
|
||||
|
||||
if (rdp->state == CONNECTION_STATE_ACTIVE)
|
||||
if (rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE)
|
||||
return TRUE;
|
||||
|
||||
Sleep(100);
|
||||
|
||||
@ -2780,7 +2780,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, rdpSettings* setti
|
||||
Stream_Read_UINT32(&sub, captureFlags); /* captureFlags (4 bytes) */
|
||||
Stream_Read_UINT32(&sub, rfxCapsLength); /* capsLength (4 bytes) */
|
||||
settings->RemoteFxCaptureFlags = captureFlags;
|
||||
settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? TRUE : FALSE;
|
||||
settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? FALSE : TRUE;
|
||||
|
||||
if (rfxCapsLength)
|
||||
{
|
||||
|
||||
@ -188,6 +188,7 @@
|
||||
|
||||
static int rdp_client_connect_finalize(rdpRdp* rdp);
|
||||
static BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp);
|
||||
static BOOL rdp_set_state(rdpRdp* rdp, CONNECTION_STATE state);
|
||||
|
||||
static BOOL rdp_client_reset_codecs(rdpContext* context)
|
||||
{
|
||||
@ -358,7 +359,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
rdp->transport->ReceiveExtra = rdp;
|
||||
transport_set_blocking_mode(rdp->transport, FALSE);
|
||||
|
||||
if (rdp->state != CONNECTION_STATE_NLA)
|
||||
if (rdp_get_state(rdp) != CONNECTION_STATE_NLA)
|
||||
{
|
||||
if (!mcs_client_begin(rdp->mcs))
|
||||
return FALSE;
|
||||
@ -372,7 +373,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (rdp->state == CONNECTION_STATE_ACTIVE)
|
||||
if (rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE)
|
||||
return TRUE;
|
||||
|
||||
Sleep(100);
|
||||
@ -1137,68 +1138,69 @@ int rdp_client_transition_to_state(rdpRdp* rdp, int state)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
WLog_DBG(TAG, "%s %s --> %s", __FUNCTION__, rdp_get_state_string(rdp), rdp_state_string(state));
|
||||
switch (state)
|
||||
{
|
||||
case CONNECTION_STATE_INITIAL:
|
||||
rdp->state = CONNECTION_STATE_INITIAL;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_INITIAL);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_NEGO:
|
||||
rdp->state = CONNECTION_STATE_NEGO;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_NEGO);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_NLA:
|
||||
rdp->state = CONNECTION_STATE_NLA;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_NLA);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CONNECT:
|
||||
rdp->state = CONNECTION_STATE_MCS_CONNECT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_CONNECT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ERECT_DOMAIN:
|
||||
rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ATTACH_USER:
|
||||
rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
|
||||
rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
|
||||
rdp->state = CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
|
||||
rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT:
|
||||
rdp->state = CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_LICENSING:
|
||||
rdp->state = CONNECTION_STATE_LICENSING;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_LICENSING);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING:
|
||||
rdp->state = CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
|
||||
rdp->state = CONNECTION_STATE_CAPABILITIES_EXCHANGE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_FINALIZATION:
|
||||
rdp->state = CONNECTION_STATE_FINALIZATION;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_FINALIZATION);
|
||||
update_reset_state(rdp->update);
|
||||
rdp->finalize_sc_pdus = 0;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
rdp->state = CONNECTION_STATE_ACTIVE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_ACTIVE);
|
||||
{
|
||||
ActivatedEventArgs activatedEvent;
|
||||
rdpContext* context = rdp->context;
|
||||
@ -1218,8 +1220,8 @@ int rdp_client_transition_to_state(rdpRdp* rdp, int state)
|
||||
ConnectionStateChangeEventArgs stateEvent;
|
||||
rdpContext* context = rdp->context;
|
||||
EventArgsInit(&stateEvent, "libfreerdp");
|
||||
stateEvent.state = rdp->state;
|
||||
stateEvent.active = rdp->state == CONNECTION_STATE_ACTIVE;
|
||||
stateEvent.state = rdp_get_state(rdp);
|
||||
stateEvent.active = rdp_get_state(rdp) == CONNECTION_STATE_ACTIVE;
|
||||
PubSub_OnConnectionStateChange(context->pubSub, context, &stateEvent);
|
||||
}
|
||||
|
||||
@ -1406,7 +1408,7 @@ BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s, UINT16 pduLength)
|
||||
{
|
||||
freerdp_peer* peer = rdp->context->peer;
|
||||
|
||||
if (rdp->state != CONNECTION_STATE_CAPABILITIES_EXCHANGE)
|
||||
if (rdp_get_state(rdp) != CONNECTION_STATE_CAPABILITIES_EXCHANGE)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_recv_confirm_active(rdp, s, pduLength))
|
||||
@ -1455,74 +1457,76 @@ int rdp_server_transition_to_state(rdpRdp* rdp, int state)
|
||||
{
|
||||
int status = 0;
|
||||
freerdp_peer* client = NULL;
|
||||
const int cstate = rdp_get_state(rdp);
|
||||
|
||||
if (rdp->state >= CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT)
|
||||
if (cstate >= CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT)
|
||||
client = rdp->context->peer;
|
||||
|
||||
if (rdp->state < CONNECTION_STATE_ACTIVE)
|
||||
if (cstate < CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
if (client)
|
||||
client->activated = FALSE;
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "%s %s --> %s", __FUNCTION__, rdp_get_state_string(rdp), rdp_state_string(state));
|
||||
switch (state)
|
||||
{
|
||||
case CONNECTION_STATE_INITIAL:
|
||||
rdp->state = CONNECTION_STATE_INITIAL;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_INITIAL);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_NEGO:
|
||||
rdp->state = CONNECTION_STATE_NEGO;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_NEGO);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CONNECT:
|
||||
rdp->state = CONNECTION_STATE_MCS_CONNECT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_CONNECT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ERECT_DOMAIN:
|
||||
rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ATTACH_USER:
|
||||
rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
|
||||
rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
|
||||
rdp->state = CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
|
||||
rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT:
|
||||
rdp->state = CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_LICENSING:
|
||||
rdp->state = CONNECTION_STATE_LICENSING;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_LICENSING);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING:
|
||||
rdp->state = CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
|
||||
rdp->state = CONNECTION_STATE_CAPABILITIES_EXCHANGE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
|
||||
rdp->AwaitCapabilities = FALSE;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_FINALIZATION:
|
||||
rdp->state = CONNECTION_STATE_FINALIZATION;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_FINALIZATION);
|
||||
rdp->finalize_sc_pdus = 0;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
rdp->state = CONNECTION_STATE_ACTIVE;
|
||||
rdp_set_state(rdp, CONNECTION_STATE_ACTIVE);
|
||||
update_reset_state(rdp->update);
|
||||
|
||||
if (client)
|
||||
@ -1539,7 +1543,7 @@ int rdp_server_transition_to_state(rdpRdp* rdp, int state)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rdp->state >= CONNECTION_STATE_ACTIVE)
|
||||
if (rdp_get_state(rdp) >= CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
IFCALLRET(client->Activate, client->activated, client);
|
||||
|
||||
@ -1573,7 +1577,7 @@ const char* rdp_client_connection_state_string(int state)
|
||||
}
|
||||
}
|
||||
|
||||
const char* rdp_server_connection_state_string(int state)
|
||||
const char* rdp_state_string(CONNECTION_STATE state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
@ -1612,9 +1616,21 @@ const char* rdp_server_connection_state_string(int state)
|
||||
}
|
||||
}
|
||||
|
||||
int rdp_client_get_state(rdpRdp* rdp)
|
||||
CONNECTION_STATE rdp_get_state(rdpRdp* rdp)
|
||||
{
|
||||
if (!rdp)
|
||||
return -1;
|
||||
WINPR_ASSERT(rdp);
|
||||
return rdp->state;
|
||||
}
|
||||
|
||||
BOOL rdp_set_state(rdpRdp* rdp, CONNECTION_STATE state)
|
||||
{
|
||||
WINPR_ASSERT(rdp);
|
||||
rdp->state = state;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char* rdp_get_state_string(rdpRdp* rdp)
|
||||
{
|
||||
int state = rdp_get_state(rdp);
|
||||
return rdp_state_string(state);
|
||||
}
|
||||
|
||||
@ -30,25 +30,6 @@
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/api.h>
|
||||
|
||||
enum CONNECTION_STATE
|
||||
{
|
||||
CONNECTION_STATE_INITIAL,
|
||||
CONNECTION_STATE_NEGO,
|
||||
CONNECTION_STATE_NLA,
|
||||
CONNECTION_STATE_MCS_CONNECT,
|
||||
CONNECTION_STATE_MCS_ERECT_DOMAIN,
|
||||
CONNECTION_STATE_MCS_ATTACH_USER,
|
||||
CONNECTION_STATE_MCS_CHANNEL_JOIN,
|
||||
CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT,
|
||||
CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE,
|
||||
CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT,
|
||||
CONNECTION_STATE_LICENSING,
|
||||
CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING,
|
||||
CONNECTION_STATE_CAPABILITIES_EXCHANGE,
|
||||
CONNECTION_STATE_FINALIZATION,
|
||||
CONNECTION_STATE_ACTIVE
|
||||
};
|
||||
|
||||
enum CLIENT_CONNECTION_STATE
|
||||
{
|
||||
CLIENT_STATE_INITIAL,
|
||||
@ -66,8 +47,9 @@ FREERDP_LOCAL BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL int rdp_client_connect_license(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL int rdp_client_transition_to_state(rdpRdp* rdp, int state);
|
||||
FREERDP_LOCAL const char* rdp_client_connection_state_string(int state);
|
||||
FREERDP_LOCAL int rdp_client_get_state(rdpRdp* rdp);
|
||||
|
||||
FREERDP_LOCAL CONNECTION_STATE rdp_get_state(rdpRdp* rdp);
|
||||
FREERDP_LOCAL const char* rdp_state_string(CONNECTION_STATE state);
|
||||
|
||||
FREERDP_LOCAL BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s);
|
||||
@ -78,6 +60,8 @@ FREERDP_LOCAL BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s, UIN
|
||||
FREERDP_LOCAL BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL BOOL rdp_server_reactivate(rdpRdp* rdp);
|
||||
FREERDP_LOCAL int rdp_server_transition_to_state(rdpRdp* rdp, int state);
|
||||
FREERDP_LOCAL const char* rdp_server_connection_state_string(int state);
|
||||
FREERDP_LOCAL const char* rdp_get_state_string(rdpRdp* rdp);
|
||||
|
||||
FREERDP_LOCAL const char* rdp_client_connection_state_string(int state);
|
||||
|
||||
#endif /* FREERDP_LIB_CORE_CONNECTION_H */
|
||||
|
||||
@ -948,7 +948,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t
|
||||
goto fail;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
state = rdp_client_get_state(rdp);
|
||||
state = rdp_get_state(rdp);
|
||||
if (state != CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
WLog_WARN(TAG, "[%s] called before activation [%s]", __FUNCTION__,
|
||||
|
||||
@ -1135,3 +1135,14 @@ const char* freerdp_nego_get_routing_token(rdpContext* context, DWORD* length)
|
||||
|
||||
return (const char*)nego_get_routing_token(context->rdp->nego, length);
|
||||
}
|
||||
|
||||
CONNECTION_STATE freerdp_get_state(rdpContext* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
return rdp_get_state(context->rdp);
|
||||
}
|
||||
|
||||
const char* freerdp_state_string(CONNECTION_STATE state)
|
||||
{
|
||||
return rdp_state_string(state);
|
||||
}
|
||||
|
||||
@ -203,7 +203,6 @@ static BOOL freerdp_peer_initialize(freerdp_peer* client)
|
||||
settings->ServerMode = TRUE;
|
||||
settings->FrameAcknowledge = 0;
|
||||
settings->LocalConnection = client->local;
|
||||
rdp->state = CONNECTION_STATE_INITIAL;
|
||||
|
||||
if (settings->RdpKeyFile)
|
||||
{
|
||||
@ -475,13 +474,13 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
freerdp_peer* client = (freerdp_peer*)extra;
|
||||
rdpRdp* rdp = client->context->rdp;
|
||||
|
||||
switch (rdp->state)
|
||||
switch (rdp_get_state(rdp))
|
||||
{
|
||||
case CONNECTION_STATE_INITIAL:
|
||||
if (!rdp_server_accept_nego(rdp, s))
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - rdp_server_accept_nego() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -510,7 +509,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_server_accept_mcs_connect_initial() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -522,7 +521,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_server_accept_mcs_erect_domain_request() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -534,7 +533,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_server_accept_mcs_attach_user_request() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -546,7 +545,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_server_accept_mcs_channel_join_request() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -560,7 +559,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_server_establish_keys() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -578,7 +577,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_recv_client_info() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -606,7 +605,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - callback internal "
|
||||
"error, aborting",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
|
||||
case LICENSE_CB_ABORT:
|
||||
@ -641,7 +640,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_send_demand_active() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -654,7 +653,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"peer_recv_pdu() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -670,7 +669,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"peer_recv_pdu() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -681,7 +680,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
if (peer_recv_pdu(client, s) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - peer_recv_pdu() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -691,15 +690,14 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
if (peer_recv_pdu(client, s) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - peer_recv_pdu() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "%s state %d", rdp_server_connection_state_string(rdp->state),
|
||||
rdp->state);
|
||||
WLog_ERR(TAG, "%s state %d", rdp_state_string(rdp_get_state(rdp)), rdp_get_state(rdp));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -745,6 +743,245 @@ static BOOL freerdp_peer_send_channel_data(freerdp_peer* client, UINT16 channelI
|
||||
return rdp_send_channel_data(client->context->rdp, channelId, data, size);
|
||||
}
|
||||
|
||||
static BOOL freerdp_peer_send_server_redirection_pdu(
|
||||
freerdp_peer* peer, UINT32 sessionId, const char* targetNetAddress, const char* routingToken,
|
||||
const char* userName, const char* domain, const char* password, const char* targetFQDN,
|
||||
const char* targetNetBiosName, DWORD tsvUrlLength, const BYTE* tsvUrl,
|
||||
UINT32 targetNetAddressesCount, const char** targetNetAddresses)
|
||||
{
|
||||
wStream* s = rdp_send_stream_pdu_init(peer->context->rdp);
|
||||
UINT16 length;
|
||||
UINT32 redirFlags;
|
||||
|
||||
UINT32 targetNetAddressLength;
|
||||
UINT32 loadBalanceInfoLength;
|
||||
UINT32 userNameLength;
|
||||
UINT32 domainLength;
|
||||
UINT32 passwordLength;
|
||||
UINT32 targetFQDNLength;
|
||||
UINT32 targetNetBiosNameLength;
|
||||
UINT32 targetNetAddressesLength;
|
||||
UINT32* targetNetAddressesWLength;
|
||||
|
||||
LPWSTR targetNetAddressW = NULL;
|
||||
LPWSTR userNameW = NULL;
|
||||
LPWSTR domainW = NULL;
|
||||
LPWSTR passwordW = NULL;
|
||||
LPWSTR targetFQDNW = NULL;
|
||||
LPWSTR targetNetBiosNameW = NULL;
|
||||
LPWSTR* targetNetAddressesW = NULL;
|
||||
|
||||
length = 12; /* Flags (2) + length (2) + sessionId (4) + redirection flags (4) */
|
||||
redirFlags = 0;
|
||||
|
||||
if (targetNetAddress)
|
||||
{
|
||||
redirFlags |= LB_TARGET_NET_ADDRESS;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetAddress, -1, &targetNetAddressW, 0);
|
||||
targetNetAddressLength = (strlen(targetNetAddress) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + targetNetAddressLength;
|
||||
}
|
||||
|
||||
if (routingToken)
|
||||
{
|
||||
redirFlags |= LB_LOAD_BALANCE_INFO;
|
||||
loadBalanceInfoLength =
|
||||
13 + strlen(routingToken) + 2; /* Add routing token prefix and suffix */
|
||||
length += 4 + loadBalanceInfoLength;
|
||||
}
|
||||
|
||||
if (userName)
|
||||
{
|
||||
redirFlags |= LB_USERNAME;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)userName, -1, &userNameW, 0);
|
||||
userNameLength = (strlen(userName) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + userNameLength;
|
||||
}
|
||||
|
||||
if (domain)
|
||||
{
|
||||
redirFlags |= LB_DOMAIN;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)domain, -1, &domainW, 0);
|
||||
domainLength = (strlen(domain) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + domainLength;
|
||||
}
|
||||
|
||||
if (password)
|
||||
{
|
||||
redirFlags |= LB_PASSWORD;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)password, -1, &passwordW, 0);
|
||||
passwordLength = (strlen(password) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + passwordLength;
|
||||
}
|
||||
|
||||
if (targetFQDN)
|
||||
{
|
||||
redirFlags |= LB_TARGET_FQDN;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetFQDN, -1, &targetFQDNW, 0);
|
||||
targetFQDNLength = (strlen(targetFQDN) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + targetFQDNLength;
|
||||
}
|
||||
|
||||
if (targetNetBiosName)
|
||||
{
|
||||
redirFlags |= LB_TARGET_NETBIOS_NAME;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetBiosName, -1, &targetNetBiosNameW, 0);
|
||||
targetNetBiosNameLength = (strlen(targetNetBiosName) + 1) * sizeof(WCHAR);
|
||||
|
||||
length += 4 + targetNetBiosNameLength;
|
||||
}
|
||||
|
||||
if (tsvUrl)
|
||||
{
|
||||
redirFlags |= LB_CLIENT_TSV_URL;
|
||||
length += 4 + tsvUrlLength;
|
||||
}
|
||||
|
||||
if (targetNetAddresses)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
redirFlags |= LB_TARGET_NET_ADDRESSES;
|
||||
|
||||
targetNetAddressesLength = 0;
|
||||
targetNetAddressesW = calloc(targetNetAddressesCount, sizeof(LPWSTR));
|
||||
targetNetAddressesWLength = calloc(targetNetAddressesCount, sizeof(UINT32));
|
||||
for (i = 0; i < targetNetAddressesCount; i++)
|
||||
{
|
||||
ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetAddresses[i], -1, &targetNetAddressesW[i],
|
||||
0);
|
||||
targetNetAddressesWLength[i] = (strlen(targetNetAddresses[i]) + 1) * sizeof(WCHAR);
|
||||
targetNetAddressesLength += 4 + targetNetAddressesWLength[i];
|
||||
}
|
||||
|
||||
length += 4 + 4 + targetNetAddressesLength;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, 0);
|
||||
Stream_Write_UINT16(s, SEC_REDIRECTION_PKT);
|
||||
Stream_Write_UINT16(s, length);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, length))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sessionId)
|
||||
Stream_Write_UINT32(s, sessionId);
|
||||
else
|
||||
Stream_Write_UINT32(s, 0);
|
||||
|
||||
Stream_Write_UINT32(s, redirFlags);
|
||||
|
||||
if (redirFlags & LB_TARGET_NET_ADDRESS)
|
||||
{
|
||||
Stream_Write_UINT32(s, targetNetAddressLength);
|
||||
Stream_Write(s, targetNetAddressW, targetNetAddressLength);
|
||||
free(targetNetAddressW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_LOAD_BALANCE_INFO)
|
||||
{
|
||||
Stream_Write_UINT32(s, loadBalanceInfoLength);
|
||||
Stream_Write(s, "Cookie: msts=", 13);
|
||||
Stream_Write(s, routingToken, strlen(routingToken));
|
||||
Stream_Write_UINT8(s, 0x0d);
|
||||
Stream_Write_UINT8(s, 0x0a);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_USERNAME)
|
||||
{
|
||||
Stream_Write_UINT32(s, userNameLength);
|
||||
Stream_Write(s, userNameW, userNameLength);
|
||||
free(userNameW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_DOMAIN)
|
||||
{
|
||||
Stream_Write_UINT32(s, domainLength);
|
||||
Stream_Write(s, domainW, domainLength);
|
||||
free(domainW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_PASSWORD)
|
||||
{
|
||||
Stream_Write_UINT32(s, passwordLength);
|
||||
Stream_Write(s, passwordW, passwordLength);
|
||||
free(passwordW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_FQDN)
|
||||
{
|
||||
Stream_Write_UINT32(s, targetFQDNLength);
|
||||
Stream_Write(s, targetFQDNW, targetFQDNLength);
|
||||
free(targetFQDNW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_NETBIOS_NAME)
|
||||
{
|
||||
Stream_Write_UINT32(s, targetNetBiosNameLength);
|
||||
Stream_Write(s, targetNetBiosNameW, targetNetBiosNameLength);
|
||||
free(targetNetBiosNameW);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_CLIENT_TSV_URL)
|
||||
{
|
||||
Stream_Write_UINT32(s, tsvUrlLength);
|
||||
Stream_Write(s, tsvUrl, tsvUrlLength);
|
||||
}
|
||||
|
||||
if (redirFlags & LB_TARGET_NET_ADDRESSES)
|
||||
{
|
||||
UINT32 i;
|
||||
Stream_Write_UINT32(s, targetNetAddressesLength);
|
||||
Stream_Write_UINT32(s, targetNetAddressesCount);
|
||||
for (i = 0; i < targetNetAddressesCount; i++)
|
||||
{
|
||||
Stream_Write_UINT32(s, targetNetAddressesWLength[i]);
|
||||
Stream_Write(s, targetNetAddressesW[i], targetNetAddressesWLength[i]);
|
||||
free(targetNetAddressesW[i]);
|
||||
}
|
||||
free(targetNetAddressesW);
|
||||
free(targetNetAddressesWLength);
|
||||
}
|
||||
|
||||
Stream_Write_UINT8(s, 0);
|
||||
rdp_send_pdu(peer->context->rdp, s, PDU_TYPE_SERVER_REDIRECTION, 0);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free(targetNetAddressW);
|
||||
free(userNameW);
|
||||
free(domainW);
|
||||
free(passwordW);
|
||||
free(targetFQDNW);
|
||||
free(targetNetBiosNameW);
|
||||
free(targetNetAddressesWLength);
|
||||
|
||||
if (targetNetAddressesCount > 0)
|
||||
{
|
||||
UINT32 i;
|
||||
for (i = 0; i < targetNetAddressesCount; i++)
|
||||
free(targetNetAddressesW[i]);
|
||||
free(targetNetAddressesW);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
|
||||
{
|
||||
rdpTransport* transport = peer->context->rdp->transport;
|
||||
@ -980,6 +1217,7 @@ freerdp_peer* freerdp_peer_new(int sockfd)
|
||||
client->Close = freerdp_peer_close;
|
||||
client->Disconnect = freerdp_peer_disconnect;
|
||||
client->SendChannelData = freerdp_peer_send_channel_data;
|
||||
client->SendServerRedirection = freerdp_peer_send_server_redirection_pdu;
|
||||
client->IsWriteBlocked = freerdp_peer_is_write_blocked;
|
||||
client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
|
||||
client->HasMoreToRead = freerdp_peer_has_more_to_read;
|
||||
|
||||
@ -1502,13 +1502,14 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
* enters the active state, an auto-detect PDU can be received
|
||||
* on the MCS message channel.
|
||||
*/
|
||||
if ((rdp->state > CONNECTION_STATE_MCS_CHANNEL_JOIN) && (rdp->state < CONNECTION_STATE_ACTIVE))
|
||||
if ((rdp_get_state(rdp) > CONNECTION_STATE_MCS_CHANNEL_JOIN) &&
|
||||
(rdp_get_state(rdp) < CONNECTION_STATE_ACTIVE))
|
||||
{
|
||||
if (rdp_client_connect_auto_detect(rdp, s))
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (rdp->state)
|
||||
switch (rdp_get_state(rdp))
|
||||
{
|
||||
case CONNECTION_STATE_NLA:
|
||||
if (nla_get_state(rdp->nla) < NLA_STATE_AUTH_INFO)
|
||||
@ -1516,7 +1517,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
if (nla_recv_pdu(rdp->nla, s) < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - nla_recv_pdu() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1527,7 +1528,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
if (nego_get_state(rdp->nego) != NEGO_STATE_FINAL)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - nego_recv() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1567,7 +1568,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
if (!mcs_client_begin(rdp->mcs))
|
||||
{
|
||||
WLog_ERR(TAG, "%s: %s - mcs_client_begin() fail", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state));
|
||||
rdp_state_string(rdp_get_state(rdp)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1618,7 +1619,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_ERR(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_client_connect_mcs_channel_join_confirm() fail",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state));
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)));
|
||||
status = -1;
|
||||
}
|
||||
|
||||
@ -1629,7 +1630,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
|
||||
if (status < 0)
|
||||
WLog_DBG(TAG, "%s: %s - rdp_client_connect_license() - %i", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state), status);
|
||||
rdp_state_string(rdp_get_state(rdp)), status);
|
||||
|
||||
break;
|
||||
|
||||
@ -1640,7 +1641,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
WLog_DBG(TAG,
|
||||
"%s: %s - "
|
||||
"rdp_client_connect_demand_active() - %i",
|
||||
__FUNCTION__, rdp_server_connection_state_string(rdp->state), status);
|
||||
__FUNCTION__, rdp_state_string(rdp_get_state(rdp)), status);
|
||||
|
||||
break;
|
||||
|
||||
@ -1655,7 +1656,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
|
||||
if (status < 0)
|
||||
WLog_DBG(TAG, "%s: %s - rdp_recv_pdu() - %i", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state), status);
|
||||
rdp_state_string(rdp_get_state(rdp)), status);
|
||||
|
||||
break;
|
||||
|
||||
@ -1664,13 +1665,13 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
|
||||
if (status < 0)
|
||||
WLog_DBG(TAG, "%s: %s - rdp_recv_pdu() - %i", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state), status);
|
||||
rdp_state_string(rdp_get_state(rdp)), status);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "%s: %s state %d", __FUNCTION__,
|
||||
rdp_server_connection_state_string(rdp->state), rdp->state);
|
||||
WLog_ERR(TAG, "%s: %s state %d", __FUNCTION__, rdp_state_string(rdp_get_state(rdp)),
|
||||
rdp_get_state(rdp));
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
|
||||
struct rdp_rdp
|
||||
{
|
||||
int state;
|
||||
CONNECTION_STATE state;
|
||||
freerdp* instance;
|
||||
rdpContext* context;
|
||||
rdpNla* nla;
|
||||
|
||||
@ -94,6 +94,9 @@ struct p_client_context
|
||||
UINT64 frames_count;
|
||||
|
||||
wHashTable* vc_ids; /* channel_name -> channel_id map */
|
||||
|
||||
BOOL input_state_sync_pending;
|
||||
UINT32 input_state;
|
||||
};
|
||||
typedef struct p_client_context pClientContext;
|
||||
|
||||
|
||||
@ -23,11 +23,28 @@
|
||||
#include "pf_context.h"
|
||||
#include "pf_modules.h"
|
||||
|
||||
static BOOL pf_server_check_and_sync_input_state(pClientContext* pc)
|
||||
{
|
||||
if (freerdp_get_state(&pc->context) < CONNECTION_STATE_ACTIVE)
|
||||
return FALSE;
|
||||
if (pc->input_state_sync_pending)
|
||||
{
|
||||
BOOL rc = freerdp_input_send_synchronize_event(pc->context.input, pc->input_state);
|
||||
if (rc)
|
||||
pc->input_state_sync_pending = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pf_server_synchronize_event(rdpInput* input, UINT32 flags)
|
||||
{
|
||||
pServerContext* ps = (pServerContext*)input->context;
|
||||
pClientContext* pc = ps->pdata->pc;
|
||||
return freerdp_input_send_synchronize_event(pc->context.input, flags);
|
||||
|
||||
pc->input_state = flags;
|
||||
pc->input_state_sync_pending = TRUE;
|
||||
pf_server_check_and_sync_input_state(pc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pf_server_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
@ -37,6 +54,9 @@ static BOOL pf_server_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
proxyConfig* config = ps->pdata->config;
|
||||
proxyKeyboardEventInfo event;
|
||||
|
||||
if (!pf_server_check_and_sync_input_state(pc))
|
||||
return TRUE;
|
||||
|
||||
if (!config->Keyboard)
|
||||
return TRUE;
|
||||
|
||||
@ -55,6 +75,9 @@ static BOOL pf_server_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT
|
||||
pClientContext* pc = ps->pdata->pc;
|
||||
proxyConfig* config = ps->pdata->config;
|
||||
|
||||
if (!pf_server_check_and_sync_input_state(pc))
|
||||
return TRUE;
|
||||
|
||||
if (!config->Keyboard)
|
||||
return TRUE;
|
||||
|
||||
@ -68,6 +91,9 @@ static BOOL pf_server_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1
|
||||
proxyConfig* config = ps->pdata->config;
|
||||
proxyMouseEventInfo event;
|
||||
|
||||
if (!pf_server_check_and_sync_input_state(pc))
|
||||
return TRUE;
|
||||
|
||||
if (!config->Mouse)
|
||||
return TRUE;
|
||||
|
||||
@ -87,6 +113,9 @@ static BOOL pf_server_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16
|
||||
pClientContext* pc = ps->pdata->pc;
|
||||
proxyConfig* config = ps->pdata->config;
|
||||
|
||||
if (!pf_server_check_and_sync_input_state(pc))
|
||||
return TRUE;
|
||||
|
||||
if (!config->Mouse)
|
||||
return TRUE;
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ if (NOT WIN32)
|
||||
endif()
|
||||
|
||||
# Soname versioning
|
||||
set(RAW_VERSION_STRING "2.8.1")
|
||||
set(RAW_VERSION_STRING "2.9.0")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
||||
elseif(USE_VERSION_FROM_GIT_TAG)
|
||||
@ -82,6 +82,8 @@ else()
|
||||
set(WINPR_VERSION_FULL "${WINPR_VERSION}")
|
||||
endif()
|
||||
|
||||
option(WITH_INTERNAL_MD4 "Use compiled in md4 hash functions instead of OpenSSL/MBedTLS" OFF)
|
||||
option(WITH_INTERNAL_MD5 "Use compiled in md5 hash functions instead of OpenSSL/MBedTLS" OFF)
|
||||
if(NOT IOS)
|
||||
check_include_files(stdbool.h WINPR_HAVE_STDBOOL_H)
|
||||
check_include_files(stdint.h WINPR_HAVE_STDINT_H)
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define WINPR_SSL_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
#define WINPR_SSL_INIT_DEFAULT 0x00
|
||||
#define WINPR_SSL_INIT_ALREADY_INITIALIZED 0x01
|
||||
|
||||
@ -60,10 +60,13 @@ extern "C"
|
||||
WINPR_API int _strnicmp(const char* string1, const char* string2, size_t count);
|
||||
|
||||
WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2);
|
||||
WINPR_API int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count);
|
||||
|
||||
WINPR_API size_t _wcslen(const WCHAR* str);
|
||||
WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements);
|
||||
|
||||
WINPR_API WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch);
|
||||
|
||||
WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c);
|
||||
WINPR_API WCHAR* _wcsrchr(const WCHAR* str, WCHAR c);
|
||||
|
||||
@ -73,8 +76,10 @@ extern "C"
|
||||
#else
|
||||
|
||||
#define _wcscmp wcscmp
|
||||
#define _wcsncmp wcsncmp
|
||||
#define _wcslen wcslen
|
||||
#define _wcsnlen wcsnlen
|
||||
#define _wcsstr wcsstr
|
||||
#define _wcschr wcschr
|
||||
#define _wcsrchr wcsrchr
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ extern "C"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <wctype.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/endian.h>
|
||||
|
||||
/* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
|
||||
@ -97,17 +98,39 @@ int _strnicmp(const char* string1, const char* string2, size_t count)
|
||||
|
||||
int _wcscmp(const WCHAR* string1, const WCHAR* string2)
|
||||
{
|
||||
WCHAR value1, value2;
|
||||
WINPR_ASSERT(string1);
|
||||
WINPR_ASSERT(string2);
|
||||
|
||||
while (*string1 && (*string1 == *string2))
|
||||
while (TRUE)
|
||||
{
|
||||
string1++;
|
||||
string2++;
|
||||
const WCHAR w1 = *string1++;
|
||||
const WCHAR w2 = *string2++;
|
||||
|
||||
if (w1 != w2)
|
||||
return (int)w1 - w2;
|
||||
else if ((w1 == '\0') || (w2 == '\0'))
|
||||
return (int)w1 - w2;
|
||||
}
|
||||
|
||||
Data_Read_UINT16(string1, value1);
|
||||
Data_Read_UINT16(string2, value2);
|
||||
return value1 - value2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||
{
|
||||
WINPR_ASSERT(string1);
|
||||
WINPR_ASSERT(string2);
|
||||
|
||||
for (size_t x = 0; x < count; x++)
|
||||
{
|
||||
const WCHAR a = string1[x];
|
||||
const WCHAR b = string2[x];
|
||||
|
||||
if (a != b)
|
||||
return (int)a - b;
|
||||
else if ((a == '\0') || (b == '\0'))
|
||||
return (int)a - b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _wcslen -> wcslen */
|
||||
@ -116,8 +139,7 @@ size_t _wcslen(const WCHAR* str)
|
||||
{
|
||||
const WCHAR* p = (const WCHAR*)str;
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
WINPR_ASSERT(p);
|
||||
|
||||
while (*p)
|
||||
p++;
|
||||
@ -131,8 +153,7 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||
{
|
||||
size_t x;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
WINPR_ASSERT(str);
|
||||
|
||||
for (x = 0; x < max; x++)
|
||||
{
|
||||
@ -143,6 +164,26 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||
return x;
|
||||
}
|
||||
|
||||
/* _wcsstr -> wcsstr */
|
||||
|
||||
WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch)
|
||||
{
|
||||
WINPR_ASSERT(str);
|
||||
WINPR_ASSERT(strSearch);
|
||||
|
||||
if (strSearch[0] == '\0')
|
||||
return str;
|
||||
|
||||
const size_t searchLen = _wcslen(strSearch);
|
||||
while (*str)
|
||||
{
|
||||
if (_wcsncmp(str, strSearch, searchLen) == 0)
|
||||
return str;
|
||||
str++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* _wcschr -> wcschr */
|
||||
|
||||
WCHAR* _wcschr(const WCHAR* str, WCHAR c)
|
||||
|
||||
@ -15,13 +15,26 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
winpr_module_add(
|
||||
set(SRCS
|
||||
hash.c
|
||||
rand.c
|
||||
cipher.c
|
||||
cert.c
|
||||
crypto.c
|
||||
crypto.h)
|
||||
crypto.h
|
||||
)
|
||||
if (WITH_INTERNAL_MD4)
|
||||
list(APPEND SRCS md4.c md4.h)
|
||||
endif()
|
||||
|
||||
if (WITH_INTERNAL_MD5)
|
||||
list(APPEND SRCS md5.c md5.h)
|
||||
list(APPEND SRCS hmac_md5.c hmac_md5.h)
|
||||
endif()
|
||||
|
||||
winpr_module_add(
|
||||
${SRCS}
|
||||
)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
winpr_include_directory_add(${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
@ -39,6 +39,15 @@
|
||||
#include <mbedtls/md.h>
|
||||
#endif
|
||||
|
||||
#if defined(WITH_INTERNAL_MD4)
|
||||
#include "md4.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
#include "md5.h"
|
||||
#include "hmac_md5.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* HMAC
|
||||
*/
|
||||
@ -146,41 +155,68 @@ const char* winpr_md_type_to_string(WINPR_MD_TYPE md)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct _winpr_hmac_ctx_private_st
|
||||
{
|
||||
WINPR_MD_TYPE md;
|
||||
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
WINPR_HMAC_MD5_CTX hmac_md5;
|
||||
#endif
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac;
|
||||
#endif
|
||||
#if defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t hmac;
|
||||
#endif
|
||||
};
|
||||
|
||||
WINPR_HMAC_CTX* winpr_HMAC_New(void)
|
||||
{
|
||||
WINPR_HMAC_CTX* ctx = NULL;
|
||||
WINPR_HMAC_CTX* ctx = calloc(1, sizeof(WINPR_HMAC_CTX));
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
|
||||
if (!(hmac = (HMAC_CTX*)calloc(1, sizeof(HMAC_CTX))))
|
||||
return NULL;
|
||||
if (!(ctx->hmac = (HMAC_CTX*)calloc(1, sizeof(HMAC_CTX))))
|
||||
goto fail;
|
||||
|
||||
HMAC_CTX_init(hmac);
|
||||
HMAC_CTX_init(ctx->hmac);
|
||||
#else
|
||||
|
||||
if (!(hmac = HMAC_CTX_new()))
|
||||
return NULL;
|
||||
if (!(ctx->hmac = HMAC_CTX_new()))
|
||||
goto fail;
|
||||
|
||||
#endif
|
||||
ctx = (WINPR_HMAC_CTX*)hmac;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac;
|
||||
|
||||
if (!(hmac = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t))))
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(hmac);
|
||||
ctx = (WINPR_HMAC_CTX*)hmac;
|
||||
mbedtls_md_init(&ctx->hmac);
|
||||
#endif
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
winpr_HMAC_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
ctx->md = md;
|
||||
switch (ctx->md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
hmac_md5_init(&ctx->hmac_md5, key, keylen);
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*)ctx;
|
||||
HMAC_CTX* hmac = ctx->hmac;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
if (!evp || !hmac)
|
||||
@ -197,7 +233,7 @@ BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, siz
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* hmac = &ctx->hmac;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
@ -221,8 +257,21 @@ BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, siz
|
||||
|
||||
BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
switch (ctx->md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
hmac_md5_update(&ctx->hmac_md5, input, ilen);
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*)ctx;
|
||||
HMAC_CTX* hmac = ctx->hmac;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */
|
||||
@ -234,7 +283,7 @@ BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* mdctx = &ctx->hmac;
|
||||
|
||||
if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
|
||||
return TRUE;
|
||||
@ -245,17 +294,23 @@ BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
|
||||
BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
switch (ctx->md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
if (olen < WINPR_MD5_DIGEST_LENGTH)
|
||||
return FALSE;
|
||||
hmac_md5_finalize(&ctx->hmac_md5, output);
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
hmac = (HMAC_CTX*)ctx;
|
||||
HMAC_CTX* hmac = ctx->hmac;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */
|
||||
@ -267,7 +322,7 @@ BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mdctx = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* mdctx = &ctx->hmac;
|
||||
|
||||
if (mbedtls_md_hmac_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
@ -278,8 +333,11 @@ BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
|
||||
void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*)ctx;
|
||||
HMAC_CTX* hmac = ctx->hmac;
|
||||
|
||||
if (hmac)
|
||||
{
|
||||
@ -293,15 +351,14 @@ void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
|
||||
}
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* hmac = &ctx->hmac;
|
||||
|
||||
if (hmac)
|
||||
{
|
||||
mbedtls_md_free(hmac);
|
||||
free(hmac);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen,
|
||||
@ -332,34 +389,60 @@ out:
|
||||
* Generic Digest API
|
||||
*/
|
||||
|
||||
WINPR_DIGEST_CTX* winpr_Digest_New(void)
|
||||
struct _winpr_digest_ctx_private_st
|
||||
{
|
||||
WINPR_DIGEST_CTX* ctx = NULL;
|
||||
WINPR_MD_TYPE md;
|
||||
|
||||
#if defined(WITH_INTERNAL_MD4)
|
||||
WINPR_MD4_CTX md4;
|
||||
#endif
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
WINPR_MD5_CTX md5;
|
||||
#endif
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx;
|
||||
#endif
|
||||
#if defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
WINPR_DIGEST_CTX* winpr_Digest_New(void)
|
||||
{
|
||||
WINPR_DIGEST_CTX* ctx = calloc(1, sizeof(WINPR_DIGEST_CTX));
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
mdctx = EVP_MD_CTX_create();
|
||||
ctx->mdctx = EVP_MD_CTX_create();
|
||||
#else
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
ctx->mdctx = EVP_MD_CTX_new();
|
||||
#endif
|
||||
ctx = (WINPR_DIGEST_CTX*)mdctx;
|
||||
if (!ctx->mdctx)
|
||||
goto fail;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
mdctx = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t));
|
||||
ctx->mdctx = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t));
|
||||
|
||||
if (mdctx)
|
||||
mbedtls_md_init(mdctx);
|
||||
if (!ctx->mdctx)
|
||||
goto fail;
|
||||
|
||||
ctx = (WINPR_DIGEST_CTX*)mdctx;
|
||||
mbedtls_md_init(ctx->mdctx);
|
||||
#endif
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
winpr_Digest_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, const EVP_MD* evp)
|
||||
{
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
|
||||
WINPR_ASSERT(ctx);
|
||||
EVP_MD_CTX* mdctx = ctx->mdctx;
|
||||
|
||||
if (!mdctx || !evp)
|
||||
return FALSE;
|
||||
@ -373,7 +456,8 @@ static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, const EVP_MD* evp)
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
|
||||
WINPR_ASSERT(ctx);
|
||||
mbedtls_md_context_t* mdctx = ctx->mdctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
@ -397,15 +481,16 @@ static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
|
||||
BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
/* Only MD5 is supported for FIPS allow override */
|
||||
if (md != WINPR_MD_MD5)
|
||||
return FALSE;
|
||||
|
||||
EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
EVP_MD_CTX_set_flags(ctx->mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
return winpr_Digest_Init_Internal(ctx, evp);
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
|
||||
@ -419,6 +504,25 @@ BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
|
||||
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
ctx->md = md;
|
||||
switch (md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD4)
|
||||
case WINPR_MD_MD4:
|
||||
winpr_MD4_Init(&ctx->md4);
|
||||
return TRUE;
|
||||
#endif
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
winpr_MD5_Init(&ctx->md5);
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
return winpr_Digest_Init_Internal(ctx, evp);
|
||||
@ -429,14 +533,32 @@ BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
|
||||
BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
switch (ctx->md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD4)
|
||||
case WINPR_MD_MD4:
|
||||
winpr_MD4_Update(&ctx->md4, input, ilen);
|
||||
return TRUE;
|
||||
#endif
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
winpr_MD5_Update(&ctx->md5, input, ilen);
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
|
||||
EVP_MD_CTX* mdctx = ctx->mdctx;
|
||||
|
||||
if (EVP_DigestUpdate(mdctx, input, ilen) != 1)
|
||||
return FALSE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* mdctx = ctx->mdctx;
|
||||
|
||||
if (mbedtls_md_update(mdctx, input, ilen) != 0)
|
||||
return FALSE;
|
||||
@ -447,14 +569,37 @@ BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
|
||||
BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
switch (ctx->md)
|
||||
{
|
||||
#if defined(WITH_INTERNAL_MD4)
|
||||
case WINPR_MD_MD4:
|
||||
if (olen < WINPR_MD4_DIGEST_LENGTH)
|
||||
return FALSE;
|
||||
winpr_MD4_Final(output, &ctx->md4);
|
||||
return TRUE;
|
||||
#endif
|
||||
#if defined(WITH_INTERNAL_MD5)
|
||||
case WINPR_MD_MD5:
|
||||
if (olen < WINPR_MD5_DIGEST_LENGTH)
|
||||
return FALSE;
|
||||
winpr_MD5_Final(output, &ctx->md5);
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
|
||||
EVP_MD_CTX* mdctx = ctx->mdctx;
|
||||
|
||||
if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
|
||||
return TRUE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
|
||||
mbedtls_md_context_t* mdctx = ctx->mdctx;
|
||||
|
||||
if (mbedtls_md_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
@ -465,29 +610,28 @@ BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
|
||||
|
||||
void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
|
||||
|
||||
if (mdctx)
|
||||
if (ctx->mdctx)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
EVP_MD_CTX_destroy(ctx->mdctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
EVP_MD_CTX_free(ctx->mdctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
|
||||
|
||||
if (mdctx)
|
||||
if (ctx->mdctx)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
mbedtls_md_free(ctx->mdctx);
|
||||
free(ctx->mdctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Allow_FIPS(WINPR_MD_TYPE md, const BYTE* input, size_t ilen, BYTE* output,
|
||||
|
||||
54
winpr/libwinpr/crypto/hmac_md5.c
Normal file
54
winpr/libwinpr/crypto/hmac_md5.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <assert.h>
|
||||
#include "hmac_md5.h"
|
||||
#include "md5.h"
|
||||
|
||||
void hmac_md5_init(WINPR_HMAC_MD5_CTX* ctx, unsigned char* key, size_t key_len)
|
||||
{
|
||||
const WINPR_HMAC_MD5_CTX empty = { 0 };
|
||||
unsigned char k_ipad[KEY_IOPAD_SIZE] = { 0 };
|
||||
unsigned char k_opad[KEY_IOPAD_SIZE] = { 0 };
|
||||
|
||||
assert(ctx);
|
||||
*ctx = empty;
|
||||
|
||||
if (key_len <= KEY_IOPAD_SIZE)
|
||||
{
|
||||
memcpy(k_ipad, key, key_len);
|
||||
memcpy(k_opad, key, key_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
WINPR_MD5_CTX lctx = { 0 };
|
||||
|
||||
winpr_MD5_Init(&lctx);
|
||||
winpr_MD5_Update(&lctx, key, key_len);
|
||||
winpr_MD5_Final(k_ipad, &lctx);
|
||||
memcpy(k_opad, k_ipad, KEY_IOPAD_SIZE);
|
||||
}
|
||||
for (size_t i = 0; i < KEY_IOPAD_SIZE; i++)
|
||||
{
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
winpr_MD5_Init(&ctx->icontext);
|
||||
winpr_MD5_Update(&ctx->icontext, k_ipad, KEY_IOPAD_SIZE);
|
||||
|
||||
winpr_MD5_Init(&ctx->ocontext);
|
||||
winpr_MD5_Update(&ctx->ocontext, k_opad, KEY_IOPAD_SIZE);
|
||||
}
|
||||
|
||||
void hmac_md5_update(WINPR_HMAC_MD5_CTX* ctx, unsigned char* text, size_t text_len)
|
||||
{
|
||||
assert(ctx);
|
||||
winpr_MD5_Update(&ctx->icontext, text, text_len);
|
||||
}
|
||||
|
||||
void hmac_md5_finalize(WINPR_HMAC_MD5_CTX* ctx, unsigned char* hmac)
|
||||
{
|
||||
assert(ctx);
|
||||
winpr_MD5_Final(hmac, &ctx->icontext);
|
||||
|
||||
winpr_MD5_Update(&ctx->ocontext, hmac, 16);
|
||||
winpr_MD5_Final(hmac, &ctx->ocontext);
|
||||
}
|
||||
19
winpr/libwinpr/crypto/hmac_md5.h
Normal file
19
winpr/libwinpr/crypto/hmac_md5.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef WINPR_HMAC_MD5
|
||||
#define WINPR_HMAC_MD5
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#define KEY_IOPAD_SIZE 64
|
||||
typedef struct
|
||||
{
|
||||
WINPR_MD5_CTX icontext;
|
||||
WINPR_MD5_CTX ocontext;
|
||||
} WINPR_HMAC_MD5_CTX;
|
||||
|
||||
void hmac_md5_init(WINPR_HMAC_MD5_CTX* ctx, unsigned char* key, size_t key_len);
|
||||
void hmac_md5_update(WINPR_HMAC_MD5_CTX* ctx, unsigned char* text, size_t text_len);
|
||||
void hmac_md5_finalize(WINPR_HMAC_MD5_CTX* ctx, unsigned char* hmac);
|
||||
|
||||
#endif
|
||||
266
winpr/libwinpr/crypto/md4.c
Normal file
266
winpr/libwinpr/crypto/md4.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD4 Message-Digest Algorithm (RFC 1320).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* (This is a heavily cut-down "BSD license".)
|
||||
*
|
||||
* This differs from Colin Plumb's older public domain implementation in that
|
||||
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||
* unsigned integer data type will do), there's no compile-time endianness
|
||||
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||
* the properties of the two independent implementations.
|
||||
*
|
||||
* The primary goals of this implementation are portability and ease of use.
|
||||
* It is meant to be fast, but not as fast as possible. Some known
|
||||
* optimizations are not included to reduce source code size and avoid
|
||||
* compile-time configuration.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "md4.h"
|
||||
|
||||
/*
|
||||
* The basic MD4 functions.
|
||||
*
|
||||
* F and G are optimized compared to their RFC 1320 definitions, with the
|
||||
* optimization for F borrowed from Colin Plumb's MD5 implementation.
|
||||
*/
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/*
|
||||
* The MD4 transformation for all three rounds.
|
||||
*/
|
||||
#define STEP(f, a, b, c, d, x, s) \
|
||||
(a) += f((b), (c), (d)) + (x); \
|
||||
(a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s))));
|
||||
|
||||
/*
|
||||
* SET reads 4 input bytes in little-endian byte order and stores them in a
|
||||
* properly aligned word in host byte order.
|
||||
*
|
||||
* The check for little-endian architectures that tolerate unaligned memory
|
||||
* accesses is just an optimization. Nothing will break if it fails to detect
|
||||
* a suitable architecture.
|
||||
*
|
||||
* Unfortunately, this optimization may be a C strict aliasing rules violation
|
||||
* if the caller's data buffer has effective type that cannot be aliased by
|
||||
* winpr_MD4_u32plus. In practice, this problem may occur if these MD4 routines are
|
||||
* inlined into a calling function, or with future and dangerously advanced
|
||||
* link-time optimizations. For the time being, keeping these MD4 routines in
|
||||
* their own translation unit avoids the problem.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||
#define SET(n) (*(winpr_MD4_u32plus*)&ptr[(n)*4])
|
||||
#define GET(n) SET(n)
|
||||
#else
|
||||
#define SET(n) \
|
||||
(ctx->block[(n)] = (winpr_MD4_u32plus)ptr[(n)*4] | ((winpr_MD4_u32plus)ptr[(n)*4 + 1] << 8) | \
|
||||
((winpr_MD4_u32plus)ptr[(n)*4 + 2] << 16) | \
|
||||
((winpr_MD4_u32plus)ptr[(n)*4 + 3] << 24))
|
||||
#define GET(n) (ctx->block[(n)])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||
* counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void* body(WINPR_MD4_CTX* ctx, const void* data, unsigned long size)
|
||||
{
|
||||
const unsigned char* ptr;
|
||||
winpr_MD4_u32plus a, b, c, d;
|
||||
winpr_MD4_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
const winpr_MD4_u32plus ac1 = 0x5a827999, ac2 = 0x6ed9eba1;
|
||||
|
||||
ptr = (const unsigned char*)data;
|
||||
|
||||
a = ctx->a;
|
||||
b = ctx->b;
|
||||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do
|
||||
{
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 3)
|
||||
STEP(F, d, a, b, c, SET(1), 7)
|
||||
STEP(F, c, d, a, b, SET(2), 11)
|
||||
STEP(F, b, c, d, a, SET(3), 19)
|
||||
STEP(F, a, b, c, d, SET(4), 3)
|
||||
STEP(F, d, a, b, c, SET(5), 7)
|
||||
STEP(F, c, d, a, b, SET(6), 11)
|
||||
STEP(F, b, c, d, a, SET(7), 19)
|
||||
STEP(F, a, b, c, d, SET(8), 3)
|
||||
STEP(F, d, a, b, c, SET(9), 7)
|
||||
STEP(F, c, d, a, b, SET(10), 11)
|
||||
STEP(F, b, c, d, a, SET(11), 19)
|
||||
STEP(F, a, b, c, d, SET(12), 3)
|
||||
STEP(F, d, a, b, c, SET(13), 7)
|
||||
STEP(F, c, d, a, b, SET(14), 11)
|
||||
STEP(F, b, c, d, a, SET(15), 19)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(0) + ac1, 3)
|
||||
STEP(G, d, a, b, c, GET(4) + ac1, 5)
|
||||
STEP(G, c, d, a, b, GET(8) + ac1, 9)
|
||||
STEP(G, b, c, d, a, GET(12) + ac1, 13)
|
||||
STEP(G, a, b, c, d, GET(1) + ac1, 3)
|
||||
STEP(G, d, a, b, c, GET(5) + ac1, 5)
|
||||
STEP(G, c, d, a, b, GET(9) + ac1, 9)
|
||||
STEP(G, b, c, d, a, GET(13) + ac1, 13)
|
||||
STEP(G, a, b, c, d, GET(2) + ac1, 3)
|
||||
STEP(G, d, a, b, c, GET(6) + ac1, 5)
|
||||
STEP(G, c, d, a, b, GET(10) + ac1, 9)
|
||||
STEP(G, b, c, d, a, GET(14) + ac1, 13)
|
||||
STEP(G, a, b, c, d, GET(3) + ac1, 3)
|
||||
STEP(G, d, a, b, c, GET(7) + ac1, 5)
|
||||
STEP(G, c, d, a, b, GET(11) + ac1, 9)
|
||||
STEP(G, b, c, d, a, GET(15) + ac1, 13)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(0) + ac2, 3)
|
||||
STEP(H, d, a, b, c, GET(8) + ac2, 9)
|
||||
STEP(H, c, d, a, b, GET(4) + ac2, 11)
|
||||
STEP(H, b, c, d, a, GET(12) + ac2, 15)
|
||||
STEP(H, a, b, c, d, GET(2) + ac2, 3)
|
||||
STEP(H, d, a, b, c, GET(10) + ac2, 9)
|
||||
STEP(H, c, d, a, b, GET(6) + ac2, 11)
|
||||
STEP(H, b, c, d, a, GET(14) + ac2, 15)
|
||||
STEP(H, a, b, c, d, GET(1) + ac2, 3)
|
||||
STEP(H, d, a, b, c, GET(9) + ac2, 9)
|
||||
STEP(H, c, d, a, b, GET(5) + ac2, 11)
|
||||
STEP(H, b, c, d, a, GET(13) + ac2, 15)
|
||||
STEP(H, a, b, c, d, GET(3) + ac2, 3)
|
||||
STEP(H, d, a, b, c, GET(11) + ac2, 9)
|
||||
STEP(H, c, d, a, b, GET(7) + ac2, 11)
|
||||
STEP(H, b, c, d, a, GET(15) + ac2, 15)
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while (size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
ctx->c = c;
|
||||
ctx->d = d;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void winpr_MD4_Init(WINPR_MD4_CTX* ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const void* data, unsigned long size)
|
||||
{
|
||||
winpr_MD4_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += size >> 29;
|
||||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if (used)
|
||||
{
|
||||
available = 64 - used;
|
||||
|
||||
if (size < available)
|
||||
{
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char*)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if (size >= 64)
|
||||
{
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
memcpy(ctx->buffer, data, size);
|
||||
}
|
||||
|
||||
#define OUT(dst, src) \
|
||||
(dst)[0] = (unsigned char)(src); \
|
||||
(dst)[1] = (unsigned char)((src) >> 8); \
|
||||
(dst)[2] = (unsigned char)((src) >> 16); \
|
||||
(dst)[3] = (unsigned char)((src) >> 24);
|
||||
|
||||
void winpr_MD4_Final(unsigned char* result, WINPR_MD4_CTX* ctx)
|
||||
{
|
||||
unsigned long used, available;
|
||||
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
available = 64 - used;
|
||||
|
||||
if (available < 8)
|
||||
{
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
ctx->lo <<= 3;
|
||||
OUT(&ctx->buffer[56], ctx->lo)
|
||||
OUT(&ctx->buffer[60], ctx->hi)
|
||||
|
||||
body(ctx, ctx->buffer, 64);
|
||||
|
||||
OUT(&result[0], ctx->a)
|
||||
OUT(&result[4], ctx->b)
|
||||
OUT(&result[8], ctx->c)
|
||||
OUT(&result[12], ctx->d)
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
46
winpr/libwinpr/crypto/md4.h
Normal file
46
winpr/libwinpr/crypto/md4.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD4 Message-Digest Algorithm (RFC 1320).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See md4.c for more information.
|
||||
*/
|
||||
|
||||
#if !defined(WINPR_MD4_H)
|
||||
#define WINPR_MD4_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef UINT32 winpr_MD4_u32plus;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
winpr_MD4_u32plus lo, hi;
|
||||
winpr_MD4_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
winpr_MD4_u32plus block[16];
|
||||
} WINPR_MD4_CTX;
|
||||
|
||||
extern void winpr_MD4_Init(WINPR_MD4_CTX* ctx);
|
||||
extern void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const void* data, unsigned long size);
|
||||
extern void winpr_MD4_Final(unsigned char* result, WINPR_MD4_CTX* ctx);
|
||||
|
||||
#endif
|
||||
287
winpr/libwinpr/crypto/md5.c
Normal file
287
winpr/libwinpr/crypto/md5.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* (This is a heavily cut-down "BSD license".)
|
||||
*
|
||||
* This differs from Colin Plumb's older public domain implementation in that
|
||||
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||
* unsigned integer data type will do), there's no compile-time endianness
|
||||
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||
* the properties of the two independent implementations.
|
||||
*
|
||||
* The primary goals of this implementation are portability and ease of use.
|
||||
* It is meant to be fast, but not as fast as possible. Some known
|
||||
* optimizations are not included to reduce source code size and avoid
|
||||
* compile-time configuration.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
* The basic MD5 functions.
|
||||
*
|
||||
* F and G are optimized compared to their RFC 1321 definitions for
|
||||
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
|
||||
* implementation.
|
||||
*/
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
|
||||
#define H(x, y, z) (((x) ^ (y)) ^ (z))
|
||||
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
|
||||
/*
|
||||
* The MD5 transformation for all four rounds.
|
||||
*/
|
||||
#define STEP(f, a, b, c, d, x, t, s) \
|
||||
(a) += f((b), (c), (d)) + (x) + (t); \
|
||||
(a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s)))); \
|
||||
(a) += (b);
|
||||
|
||||
/*
|
||||
* SET reads 4 input bytes in little-endian byte order and stores them in a
|
||||
* properly aligned word in host byte order.
|
||||
*
|
||||
* The check for little-endian architectures that tolerate unaligned memory
|
||||
* accesses is just an optimization. Nothing will break if it fails to detect
|
||||
* a suitable architecture.
|
||||
*
|
||||
* Unfortunately, this optimization may be a C strict aliasing rules violation
|
||||
* if the caller's data buffer has effective type that cannot be aliased by
|
||||
* MD5_u32plus. In practice, this problem may occur if these MD5 routines are
|
||||
* inlined into a calling function, or with future and dangerously advanced
|
||||
* link-time optimizations. For the time being, keeping these MD5 routines in
|
||||
* their own translation unit avoids the problem.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||
#define SET(n) (*(winpr_MD5_u32plus*)&ptr[(n)*4])
|
||||
#define GET(n) SET(n)
|
||||
#else
|
||||
#define SET(n) \
|
||||
(ctx->block[(n)] = (winpr_MD5_u32plus)ptr[(n)*4] | ((winpr_MD5_u32plus)ptr[(n)*4 + 1] << 8) | \
|
||||
((winpr_MD5_u32plus)ptr[(n)*4 + 2] << 16) | \
|
||||
((winpr_MD5_u32plus)ptr[(n)*4 + 3] << 24))
|
||||
#define GET(n) (ctx->block[(n)])
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||
* counters. There are no alignment requirements.
|
||||
*/
|
||||
static const void* body(WINPR_MD5_CTX* ctx, const void* data, unsigned long size)
|
||||
{
|
||||
const unsigned char* ptr;
|
||||
winpr_MD5_u32plus a, b, c, d;
|
||||
winpr_MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char*)data;
|
||||
|
||||
a = ctx->a;
|
||||
b = ctx->b;
|
||||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do
|
||||
{
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
|
||||
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||
|
||||
/* Round 4 */
|
||||
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while (size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
ctx->c = c;
|
||||
ctx->d = d;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void winpr_MD5_Init(WINPR_MD5_CTX* ctx)
|
||||
{
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
void winpr_MD5_Update(WINPR_MD5_CTX* ctx, const void* data, unsigned long size)
|
||||
{
|
||||
winpr_MD5_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += size >> 29;
|
||||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if (used)
|
||||
{
|
||||
available = 64 - used;
|
||||
|
||||
if (size < available)
|
||||
{
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char*)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if (size >= 64)
|
||||
{
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
memcpy(ctx->buffer, data, size);
|
||||
}
|
||||
|
||||
#define OUT(dst, src) \
|
||||
(dst)[0] = (unsigned char)(src); \
|
||||
(dst)[1] = (unsigned char)((src) >> 8); \
|
||||
(dst)[2] = (unsigned char)((src) >> 16); \
|
||||
(dst)[3] = (unsigned char)((src) >> 24);
|
||||
|
||||
void winpr_MD5_Final(unsigned char* result, WINPR_MD5_CTX* ctx)
|
||||
{
|
||||
unsigned long used, available;
|
||||
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
available = 64 - used;
|
||||
|
||||
if (available < 8)
|
||||
{
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
ctx->lo <<= 3;
|
||||
OUT(&ctx->buffer[56], ctx->lo)
|
||||
OUT(&ctx->buffer[60], ctx->hi)
|
||||
|
||||
body(ctx, ctx->buffer, 64);
|
||||
|
||||
OUT(&result[0], ctx->a)
|
||||
OUT(&result[4], ctx->b)
|
||||
OUT(&result[8], ctx->c)
|
||||
OUT(&result[12], ctx->d)
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
48
winpr/libwinpr/crypto/md5.h
Normal file
48
winpr/libwinpr/crypto/md5.h
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
/*
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||
* claimed, and the software is hereby placed in the public domain.
|
||||
* In case this attempt to disclaim copyright and place the software in the
|
||||
* public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See md5.c for more information.
|
||||
*/
|
||||
|
||||
#if !defined(WINPR_MD5_H)
|
||||
#define WINPR_MD5_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef UINT32 winpr_MD5_u32plus;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
winpr_MD5_u32plus lo, hi;
|
||||
winpr_MD5_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
winpr_MD5_u32plus block[16];
|
||||
} WINPR_MD5_CTX;
|
||||
|
||||
extern void winpr_MD5_Init(WINPR_MD5_CTX* ctx);
|
||||
extern void winpr_MD5_Update(WINPR_MD5_CTX* ctx, const void* data, unsigned long size);
|
||||
extern void winpr_MD5_Final(unsigned char* result, WINPR_MD5_CTX* ctx);
|
||||
|
||||
#endif
|
||||
@ -11,7 +11,7 @@ static const BYTE TEST_MD5_HASH[] =
|
||||
static BOOL test_crypto_hash_md5(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH] = { 0 };
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
@ -64,7 +64,7 @@ static const BYTE TEST_MD4_HASH[] =
|
||||
static BOOL test_crypto_hash_md4(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_MD4_DIGEST_LENGTH];
|
||||
BYTE hash[WINPR_MD4_DIGEST_LENGTH] = { 0 };
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
@ -117,7 +117,7 @@ static const BYTE TEST_SHA1_HASH[] =
|
||||
static BOOL test_crypto_hash_sha1(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH] = { 0 };
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
@ -168,11 +168,11 @@ static const char TEST_HMAC_MD5_DATA[] = "Hi There";
|
||||
static const BYTE TEST_HMAC_MD5_KEY[] =
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
|
||||
static const BYTE TEST_HMAC_MD5_HASH[] =
|
||||
"\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d";
|
||||
"\xb5\x79\x91\xa2\x20\x3d\x49\x2d\x73\xfb\x71\x43\xdf\xc5\x08\x28";
|
||||
|
||||
static BOOL test_crypto_hash_hmac_md5(void)
|
||||
{
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH] = { 0 };
|
||||
WINPR_HMAC_CTX* ctx;
|
||||
BOOL result = FALSE;
|
||||
|
||||
@ -193,6 +193,12 @@ static BOOL test_crypto_hash_hmac_md5(void)
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Update(ctx, (const BYTE*)TEST_HMAC_MD5_DATA,
|
||||
strnlen(TEST_HMAC_MD5_DATA, sizeof(TEST_HMAC_MD5_DATA))))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__);
|
||||
@ -225,11 +231,11 @@ static const char TEST_HMAC_SHA1_DATA[] = "Hi There";
|
||||
static const BYTE TEST_HMAC_SHA1_KEY[] =
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
|
||||
static const BYTE TEST_HMAC_SHA1_HASH[] =
|
||||
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00";
|
||||
"\xab\x23\x08\x2d\xca\x0c\x75\xea\xca\x60\x09\xc0\xb8\x8c\x2d\xf4\xf4\xbf\x88\xee";
|
||||
|
||||
static BOOL test_crypto_hash_hmac_sha1(void)
|
||||
{
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH] = { 0 };
|
||||
WINPR_HMAC_CTX* ctx;
|
||||
BOOL result = FALSE;
|
||||
|
||||
@ -250,6 +256,12 @@ static BOOL test_crypto_hash_hmac_sha1(void)
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Update(ctx, (const BYTE*)TEST_HMAC_SHA1_DATA,
|
||||
strnlen(TEST_HMAC_SHA1_DATA, sizeof(TEST_HMAC_SHA1_DATA))))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__);
|
||||
|
||||
@ -42,6 +42,12 @@
|
||||
|
||||
static BOOL g_winpr_openssl_initialized_by_winpr = FALSE;
|
||||
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||
static OSSL_PROVIDER* s_winpr_openssl_provider_fips = NULL;
|
||||
static OSSL_PROVIDER* s_winpr_openssl_provider_legacy = NULL;
|
||||
static OSSL_PROVIDER* s_winpr_openssl_provider_default = NULL;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Note from OpenSSL 1.1.0 "CHANGES":
|
||||
* OpenSSL now uses a new threading API. It is no longer necessary to
|
||||
@ -249,7 +255,11 @@ static BOOL winpr_enable_fips(DWORD flags)
|
||||
WLog_DBG(TAG, "Ensuring openssl fips mode is enabled");
|
||||
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||
OSSL_PROVIDER_load(NULL, "fips");
|
||||
s_winpr_openssl_provider_fips = OSSL_PROVIDER_load(NULL, "fips");
|
||||
if (s_winpr_openssl_provider_fips == NULL)
|
||||
{
|
||||
WLog_WARN(TAG, "OpenSSL FIPS provider failled to load");
|
||||
}
|
||||
if (!EVP_default_properties_is_fips_enabled(NULL))
|
||||
#else
|
||||
if (FIPS_mode() != 1)
|
||||
@ -313,8 +323,16 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
|
||||
|
||||
#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");
|
||||
s_winpr_openssl_provider_legacy = OSSL_PROVIDER_load(NULL, "legacy");
|
||||
if (s_winpr_openssl_provider_legacy == NULL)
|
||||
{
|
||||
WLog_WARN(TAG, "OpenSSL LEGACY provider failed to load, no md4 support available!");
|
||||
}
|
||||
s_winpr_openssl_provider_default = OSSL_PROVIDER_load(NULL, "default");
|
||||
if (s_winpr_openssl_provider_default == NULL)
|
||||
{
|
||||
WLog_WARN(TAG, "OpenSSL DEFAULT provider failed to load");
|
||||
}
|
||||
#endif
|
||||
|
||||
g_winpr_openssl_initialized_by_winpr = TRUE;
|
||||
@ -368,6 +386,11 @@ BOOL winpr_CleanupSSL(DWORD flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||
OSSL_PROVIDER_unload(s_winpr_openssl_provider_fips);
|
||||
OSSL_PROVIDER_unload(s_winpr_openssl_provider_legacy);
|
||||
OSSL_PROVIDER_unload(s_winpr_openssl_provider_default);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user