Merge branch 'master' of github.com:FreeRDP/FreeRDP
This commit is contained in:
commit
d30f66b1b7
@ -595,7 +595,7 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
|||||||
free(ent_path);
|
free(ent_path);
|
||||||
ent_path = NULL;
|
ent_path = NULL;
|
||||||
|
|
||||||
length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2;
|
length = ConvertToUnicode(sys_code_page, 0, ent->d_name, -1, &ent_path, 0) * 2;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
|
@ -118,4 +118,6 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
|||||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||||
const char* path, wStream* output);
|
const char* path, wStream* output);
|
||||||
|
|
||||||
|
extern UINT sys_code_page;
|
||||||
|
|
||||||
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
||||||
|
@ -373,7 +373,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
|
|||||||
{
|
{
|
||||||
case FileFsVolumeInformation:
|
case FileFsVolumeInformation:
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232108.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232108.aspx */
|
||||||
length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2;
|
length = ConvertToUnicode(sys_code_page, 0, volumeLabel, -1, &outStr, 0) * 2;
|
||||||
Stream_Write_UINT32(output, 17 + length); /* Length */
|
Stream_Write_UINT32(output, 17 + length); /* Length */
|
||||||
Stream_EnsureRemainingCapacity(output, 17 + length);
|
Stream_EnsureRemainingCapacity(output, 17 + length);
|
||||||
Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
|
Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
|
||||||
@ -401,7 +401,7 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
|
|||||||
|
|
||||||
case FileFsAttributeInformation:
|
case FileFsAttributeInformation:
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232101.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232101.aspx */
|
||||||
length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2;
|
length = ConvertToUnicode(sys_code_page, 0, diskType, -1, &outStr, 0) * 2;
|
||||||
Stream_Write_UINT32(output, 12 + length); /* Length */
|
Stream_Write_UINT32(output, 12 + length); /* Length */
|
||||||
Stream_EnsureRemainingCapacity(output, 12 + length);
|
Stream_EnsureRemainingCapacity(output, 12 + length);
|
||||||
Stream_Write_UINT32(output,
|
Stream_Write_UINT32(output,
|
||||||
@ -700,6 +700,8 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
|
|||||||
#define DeviceServiceEntry drive_DeviceServiceEntry
|
#define DeviceServiceEntry drive_DeviceServiceEntry
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UINT sys_code_page = 0;
|
||||||
|
|
||||||
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||||
{
|
{
|
||||||
RDPDR_DRIVE* drive;
|
RDPDR_DRIVE* drive;
|
||||||
@ -713,6 +715,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|
||||||
|
sys_code_page = CP_UTF8;
|
||||||
if (strcmp(drive->Path, "*") == 0)
|
if (strcmp(drive->Path, "*") == 0)
|
||||||
{
|
{
|
||||||
/* all drives */
|
/* all drives */
|
||||||
@ -738,6 +741,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||||||
drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
|
drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
sys_code_page = GetACP();
|
||||||
/* Special case: path[0] == '*' -> export all drives */
|
/* Special case: path[0] == '*' -> export all drives */
|
||||||
/* Special case: path[0] == '%' -> user home dir */
|
/* Special case: path[0] == '%' -> user home dir */
|
||||||
if (strcmp(drive->Path, "%") == 0)
|
if (strcmp(drive->Path, "%") == 0)
|
||||||
|
@ -518,7 +518,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
|||||||
|
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
int activate = (int)(short) LOWORD(lParam);
|
int activate = (int)(short) LOWORD(wParam);
|
||||||
if (activate != WA_INACTIVE)
|
if (activate != WA_INACTIVE)
|
||||||
{
|
{
|
||||||
g_focus_hWnd = hWnd;
|
g_focus_hWnd = hWnd;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <freerdp/addin.h>
|
#include <freerdp/addin.h>
|
||||||
#include <freerdp/settings.h>
|
#include <freerdp/settings.h>
|
||||||
#include <freerdp/client/channels.h>
|
#include <freerdp/client/channels.h>
|
||||||
|
#include <freerdp/crypto/crypto.h>
|
||||||
#include <freerdp/locale/keyboard.h>
|
#include <freerdp/locale/keyboard.h>
|
||||||
|
|
||||||
#include <freerdp/client/cmdline.h>
|
#include <freerdp/client/cmdline.h>
|
||||||
@ -141,6 +142,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
|||||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
|
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
|
||||||
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
||||||
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
||||||
|
{ "reconnect-cookie", COMMAND_LINE_VALUE_REQUIRED, "<base64 cookie>", NULL, NULL, -1, NULL, "Pass base64 reconnect cookie to the connection" },
|
||||||
|
{ "print-reconnect-cookie", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Print base64 reconnect cookie after connecting" },
|
||||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1677,6 +1680,27 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
{
|
{
|
||||||
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
CommandLineSwitchCase(arg, "reconnect-cookie")
|
||||||
|
{
|
||||||
|
BYTE *base64;
|
||||||
|
int length;
|
||||||
|
crypto_base64_decode((BYTE *) (arg->Value),
|
||||||
|
(int) strlen(arg->Value), &base64, &length);
|
||||||
|
if ((base64 != NULL) && (length == sizeof(ARC_SC_PRIVATE_PACKET)))
|
||||||
|
{
|
||||||
|
memcpy(settings->ServerAutoReconnectCookie, base64, length);
|
||||||
|
free(base64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "reconnect-cookie: invalid base64 '%s'\n",
|
||||||
|
arg->Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommandLineSwitchCase(arg, "print-reconnect-cookie")
|
||||||
|
{
|
||||||
|
settings->PrintReconnectCookie = arg->Value ? TRUE : FALSE;
|
||||||
|
}
|
||||||
CommandLineSwitchDefault(arg)
|
CommandLineSwitchDefault(arg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,7 @@ typedef struct crypto_hmac_struct* CryptoHmac;
|
|||||||
|
|
||||||
FREERDP_API CryptoHmac crypto_hmac_new(void);
|
FREERDP_API CryptoHmac crypto_hmac_new(void);
|
||||||
FREERDP_API void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
FREERDP_API void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||||
|
FREERDP_API void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||||
FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||||
FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length);
|
FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length);
|
||||||
FREERDP_API void crypto_hmac_free(CryptoHmac hmac);
|
FREERDP_API void crypto_hmac_free(CryptoHmac hmac);
|
||||||
|
@ -797,7 +797,8 @@ struct rdp_settings
|
|||||||
ALIGN64 DWORD ServerRandomLength; /* 197 */
|
ALIGN64 DWORD ServerRandomLength; /* 197 */
|
||||||
ALIGN64 BYTE* ServerCertificate; /* 198 */
|
ALIGN64 BYTE* ServerCertificate; /* 198 */
|
||||||
ALIGN64 DWORD ServerCertificateLength; /* 199 */
|
ALIGN64 DWORD ServerCertificateLength; /* 199 */
|
||||||
UINT64 padding0256[256 - 200]; /* 200 */
|
ALIGN64 BYTE* ClientRandom; /* 200 */
|
||||||
|
UINT64 padding0256[256 - 201]; /* 201 */
|
||||||
|
|
||||||
/* Client Network Data */
|
/* Client Network Data */
|
||||||
ALIGN64 UINT32 ChannelCount; /* 256 */
|
ALIGN64 UINT32 ChannelCount; /* 256 */
|
||||||
@ -873,7 +874,8 @@ struct rdp_settings
|
|||||||
ALIGN64 UINT32 AutoReconnectMaxRetries; /* 833 */
|
ALIGN64 UINT32 AutoReconnectMaxRetries; /* 833 */
|
||||||
ALIGN64 ARC_CS_PRIVATE_PACKET* ClientAutoReconnectCookie; /* 834 */
|
ALIGN64 ARC_CS_PRIVATE_PACKET* ClientAutoReconnectCookie; /* 834 */
|
||||||
ALIGN64 ARC_SC_PRIVATE_PACKET* ServerAutoReconnectCookie; /* 835 */
|
ALIGN64 ARC_SC_PRIVATE_PACKET* ServerAutoReconnectCookie; /* 835 */
|
||||||
UINT64 padding0896[896 - 835]; /* 835 */
|
ALIGN64 BOOL PrintReconnectCookie; /* 836 */
|
||||||
|
UINT64 padding0896[896 - 837]; /* 837 */
|
||||||
|
|
||||||
/* Client Info (Time Zone) */
|
/* Client Info (Time Zone) */
|
||||||
ALIGN64 TIME_ZONE_INFO* ClientTimeZone; /* 896 */
|
ALIGN64 TIME_ZONE_INFO* ClientTimeZone; /* 896 */
|
||||||
|
@ -783,7 +783,7 @@ int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U
|
|||||||
{
|
{
|
||||||
/* we have less bits than we need */
|
/* we have less bits than we need */
|
||||||
i32 = cur_byte >> (8 - cur_bits_left);
|
i32 = cur_byte >> (8 - cur_bits_left);
|
||||||
d32 |= (32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
||||||
bits_left += cur_bits_left;
|
bits_left += cur_bits_left;
|
||||||
tmp -= cur_bits_left;
|
tmp -= cur_bits_left;
|
||||||
if (cptr < cbuf + len)
|
if (cptr < cbuf + len)
|
||||||
|
@ -380,7 +380,6 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
|||||||
UINT32 length;
|
UINT32 length;
|
||||||
UINT32 key_len;
|
UINT32 key_len;
|
||||||
BYTE crypt_client_random[256 + 8];
|
BYTE crypt_client_random[256 + 8];
|
||||||
BYTE client_random[CLIENT_RANDOM_LENGTH];
|
|
||||||
|
|
||||||
if (!rdp->settings->DisableEncryption)
|
if (!rdp->settings->DisableEncryption)
|
||||||
{
|
{
|
||||||
@ -389,12 +388,15 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* encrypt client random */
|
/* encrypt client random */
|
||||||
|
if (rdp->settings->ClientRandom) free(rdp->settings->ClientRandom);
|
||||||
|
rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH);
|
||||||
|
if (rdp->settings->ClientRandom == NULL) return FALSE;
|
||||||
ZeroMemory(crypt_client_random, sizeof(crypt_client_random));
|
ZeroMemory(crypt_client_random, sizeof(crypt_client_random));
|
||||||
crypto_nonce(client_random, sizeof(client_random));
|
crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH);
|
||||||
key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
|
key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
|
||||||
mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
|
mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
|
||||||
exp = rdp->settings->RdpServerCertificate->cert_info.exponent;
|
exp = rdp->settings->RdpServerCertificate->cert_info.exponent;
|
||||||
crypto_rsa_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random);
|
crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random);
|
||||||
|
|
||||||
/* send crypt client random to server */
|
/* send crypt client random to server */
|
||||||
length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
|
length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
|
||||||
@ -416,7 +418,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
|||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
/* now calculate encrypt / decrypt and update keys */
|
/* now calculate encrypt / decrypt and update keys */
|
||||||
if (!security_establish_keys(client_random, rdp))
|
if (!security_establish_keys(rdp->settings->ClientRandom, rdp))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <freerdp/crypto/crypto.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "timezone.h"
|
#include "timezone.h"
|
||||||
|
|
||||||
@ -60,6 +62,14 @@ BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
|
|||||||
Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
|
Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
|
||||||
Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
||||||
Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
|
Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
|
||||||
|
if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0))
|
||||||
|
{
|
||||||
|
char *base64;
|
||||||
|
base64 = crypto_base64_encode((BYTE *) autoReconnectCookie,
|
||||||
|
sizeof(ARC_SC_PRIVATE_PACKET));
|
||||||
|
fprintf(stderr, "Reconnect-cookie: %s\n", base64);
|
||||||
|
free(base64);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +198,7 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
|
|||||||
|
|
||||||
cbClientDir = ConvertToUnicode(CP_UTF8, 0, settings->ClientDir, -1, &clientDir, 0) * 2;
|
cbClientDir = ConvertToUnicode(CP_UTF8, 0, settings->ClientDir, -1, &clientDir, 0) * 2;
|
||||||
|
|
||||||
cbAutoReconnectLen = (int) settings->ClientAutoReconnectCookie->cbLen;
|
cbAutoReconnectLen = (int) settings->ServerAutoReconnectCookie->cbLen;
|
||||||
|
|
||||||
Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily */
|
Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily */
|
||||||
|
|
||||||
@ -214,7 +224,41 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
|
|||||||
Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */
|
Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */
|
||||||
|
|
||||||
if (cbAutoReconnectLen > 0)
|
if (cbAutoReconnectLen > 0)
|
||||||
|
{
|
||||||
|
CryptoHmac hmac;
|
||||||
|
ARC_SC_PRIVATE_PACKET* serverCookie;
|
||||||
|
ARC_CS_PRIVATE_PACKET* clientCookie;
|
||||||
|
|
||||||
|
printf("Sending auto reconnect\n");
|
||||||
|
serverCookie = settings->ServerAutoReconnectCookie;
|
||||||
|
clientCookie = settings->ClientAutoReconnectCookie;
|
||||||
|
|
||||||
|
clientCookie->cbLen = serverCookie->cbLen;
|
||||||
|
clientCookie->version = serverCookie->version;
|
||||||
|
clientCookie->logonId = serverCookie->logonId;
|
||||||
|
|
||||||
|
hmac = crypto_hmac_new();
|
||||||
|
crypto_hmac_md5_init(hmac, serverCookie->arcRandomBits, 16);
|
||||||
|
if (settings->SelectedProtocol == PROTOCOL_RDP)
|
||||||
|
{
|
||||||
|
crypto_hmac_update(hmac, (BYTE *) (settings->ClientRandom), 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Anthony Tong's version had 16 zeroes here; I'm not sure why.
|
||||||
|
* I do know that 16 did not reconnect correctly vs Win2008RDVH,
|
||||||
|
* and 32 did.
|
||||||
|
*/
|
||||||
|
const BYTE zeros[32] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
|
||||||
|
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
||||||
|
crypto_hmac_update(hmac, zeros, 32);
|
||||||
|
}
|
||||||
|
crypto_hmac_final(hmac, clientCookie->securityVerifier, 16);
|
||||||
|
|
||||||
rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
|
rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
|
||||||
|
/* mark as used */
|
||||||
|
settings->ServerAutoReconnectCookie->cbLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* reserved1 (2 bytes) */
|
/* reserved1 (2 bytes) */
|
||||||
/* reserved2 (2 bytes) */
|
/* reserved2 (2 bytes) */
|
||||||
|
@ -786,6 +786,7 @@ void freerdp_settings_free(rdpSettings* settings)
|
|||||||
free(settings->ClientHostname);
|
free(settings->ClientHostname);
|
||||||
free(settings->ClientProductId);
|
free(settings->ClientProductId);
|
||||||
free(settings->ServerRandom);
|
free(settings->ServerRandom);
|
||||||
|
if (settings->ClientRandom) free(settings->ClientRandom);
|
||||||
free(settings->ServerCertificate);
|
free(settings->ServerCertificate);
|
||||||
free(settings->RdpKeyFile);
|
free(settings->RdpKeyFile);
|
||||||
certificate_free(settings->RdpServerCertificate);
|
certificate_free(settings->RdpServerCertificate);
|
||||||
|
@ -132,6 +132,11 @@ void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
|||||||
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
|
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||||
|
{
|
||||||
|
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||||
{
|
{
|
||||||
HMAC_Update(&hmac->hmac_ctx, data, length);
|
HMAC_Update(&hmac->hmac_ctx, data, length);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/synch.h>
|
#include <winpr/synch.h>
|
||||||
@ -49,6 +50,64 @@
|
|||||||
|
|
||||||
#include "../pipe/pipe.h"
|
#include "../pipe/pipe.h"
|
||||||
|
|
||||||
|
/* Drop in replacement for the linux pthread_timedjoin_np and
|
||||||
|
* pthread_mutex_timedlock functions.
|
||||||
|
*/
|
||||||
|
#if !defined(HAVE_PTHREAD_GNU_EXT)
|
||||||
|
#include <pthread.h>
|
||||||
|
static int pthread_timedjoin_np(pthread_t td, void **res,
|
||||||
|
struct timespec *timeout)
|
||||||
|
{
|
||||||
|
struct timeval timenow;
|
||||||
|
struct timespec sleepytime;
|
||||||
|
/* This is just to avoid a completely busy wait */
|
||||||
|
sleepytime.tv_sec = 0;
|
||||||
|
sleepytime.tv_nsec = 10000000; /* 10ms */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (pthread_kill(td, 0))
|
||||||
|
return pthread_join(td, res);
|
||||||
|
|
||||||
|
nanosleep(&sleepytime, NULL);
|
||||||
|
|
||||||
|
gettimeofday (&timenow, NULL);
|
||||||
|
if (timenow.tv_sec >= timeout->tv_sec &&
|
||||||
|
(timenow.tv_usec * 1000) >= timeout->tv_nsec) {
|
||||||
|
return ETIMEDOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (TRUE);
|
||||||
|
|
||||||
|
return ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pthread_mutex_timedlock(pthread_mutex_t *mutex,
|
||||||
|
const struct timespec *timeout)
|
||||||
|
{
|
||||||
|
struct timeval timenow;
|
||||||
|
struct timespec sleepytime;
|
||||||
|
int retcode;
|
||||||
|
|
||||||
|
/* This is just to avoid a completely busy wait */
|
||||||
|
sleepytime.tv_sec = 0;
|
||||||
|
sleepytime.tv_nsec = 10000000; /* 10ms */
|
||||||
|
|
||||||
|
while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
|
||||||
|
gettimeofday (&timenow, NULL);
|
||||||
|
|
||||||
|
if (timenow.tv_sec >= timeout->tv_sec &&
|
||||||
|
(timenow.tv_usec * 1000) >= timeout->tv_nsec) {
|
||||||
|
return ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nanosleep (&sleepytime, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
|
static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
|
||||||
{
|
{
|
||||||
ts->tv_sec += dwMilliseconds / 1000L;
|
ts->tv_sec += dwMilliseconds / 1000L;
|
||||||
@ -81,24 +140,28 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
{
|
{
|
||||||
if (dwMilliseconds != INFINITE)
|
if (dwMilliseconds != INFINITE)
|
||||||
{
|
{
|
||||||
#if HAVE_PTHREAD_GNU_EXT
|
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
|
|
||||||
|
/* pthread_timedjoin_np returns ETIMEDOUT in case the timeout is 0,
|
||||||
|
* so set it to the smallest value to get a proper return value. */
|
||||||
|
if (dwMilliseconds == 0)
|
||||||
|
dwMilliseconds ++;
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||||
ts_add_ms(&timeout, dwMilliseconds);
|
ts_add_ms(&timeout, dwMilliseconds);
|
||||||
|
|
||||||
status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout);
|
status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout);
|
||||||
#else
|
if (ETIMEDOUT == status)
|
||||||
fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__);
|
return WAIT_TIMEOUT;
|
||||||
assert(0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = pthread_join(thread->thread, &thread_status);
|
status = pthread_join(thread->thread, &thread_status);
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
|
{
|
||||||
fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n",
|
fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n",
|
||||||
status, strerror(status));
|
status, strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
if (thread_status)
|
if (thread_status)
|
||||||
thread->dwExitCode = ((DWORD) (size_t) thread_status);
|
thread->dwExitCode = ((DWORD) (size_t) thread_status);
|
||||||
@ -119,11 +182,11 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
}
|
}
|
||||||
else if (Type == HANDLE_TYPE_MUTEX)
|
else if (Type == HANDLE_TYPE_MUTEX)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
WINPR_MUTEX* mutex;
|
WINPR_MUTEX* mutex;
|
||||||
|
|
||||||
mutex = (WINPR_MUTEX*) Object;
|
mutex = (WINPR_MUTEX*) Object;
|
||||||
|
|
||||||
#if HAVE_PTHREAD_GNU_EXT
|
|
||||||
if (dwMilliseconds != INFINITE)
|
if (dwMilliseconds != INFINITE)
|
||||||
{
|
{
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
@ -131,10 +194,11 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||||
ts_add_ms(&timeout, dwMilliseconds);
|
ts_add_ms(&timeout, dwMilliseconds);
|
||||||
|
|
||||||
pthread_mutex_timedlock(&mutex->mutex, &timeout);
|
status = pthread_mutex_timedlock(&mutex->mutex, &timeout);
|
||||||
|
if (ETIMEDOUT == status)
|
||||||
|
return WAIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex->mutex);
|
pthread_mutex_lock(&mutex->mutex);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user