1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-19 01:33:18 +00:00

MeshAgent for MeshCentral2 Beta2 with improved crypto.

This commit is contained in:
Ylian Saint-Hilaire
2017-10-25 21:08:41 -07:00
parent 0a7e84849d
commit 34e09c2304
53 changed files with 1778 additions and 551 deletions

View File

@@ -128,7 +128,11 @@ void ILibAsyncServerSocket_OnInterruptSink(ILibAsyncSocket_SocketModule socketMo
struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)user;
if (data == NULL) return;
if (data->module->OnInterrupt != NULL) data->module->OnInterrupt(data->module, socketModule, data->user);
free(user);
if (ILibAsyncSocket_GetUser(socketModule) != NULL)
{
free(user);
ILibAsyncSocket_SetUser(socketModule, NULL);
}
}
//
// Chain PreSelect handler
@@ -421,9 +425,14 @@ void ILibAsyncServerSocket_OnDisconnectSink(ILibAsyncSocket_SocketModule socketM
// Pass this Disconnect event up
if (data == NULL) return;
if (data->module->OnDisconnect != NULL) data->module->OnDisconnect(data->module, socketModule, data->user);
if (ILibAsyncSocket_GetUser(socketModule) != NULL)
{
free(data);
ILibAsyncSocket_SetUser(socketModule, NULL);
}
// If the chain is shutting down, we need to free some resources
if (ILibIsChainBeingDestroyed(data->module->ChainLink.ParentChain) == 0) { free(data); data = NULL; }
//if (ILibIsChainBeingDestroyed(data->module->ChainLink.ParentChain) == 0) { free(data); data = NULL; }
}
//
// Internal method dispatched by the OnSendOK event of the underlying ILibAsyncSocket

View File

@@ -1831,8 +1831,8 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
{
// OpenSSL returned an error
TRY_TO_SEND = 0;
bytesSent = SSL_get_error(module->ssl, bytesSent);
if (bytesSent != SSL_ERROR_WANT_WRITE && bytesSent != SSL_ERROR_WANT_READ)
int sslerr = SSL_get_error(module->ssl, -1);
if (sslerr != SSL_ERROR_WANT_WRITE && sslerr != SSL_ERROR_WANT_READ)
{
// There was an error sending
ILibAsyncSocket_ClearPendingSend(socketModule);
@@ -1848,7 +1848,7 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
if (module->PendingSend_Head == NULL && bytesSent != -1) { TriggerSendOK = 1; }
SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PostSelect", 2, module);)
sem_post(&(module->SendLock));
if (TriggerSendOK != 0)
if (TriggerSendOK != 0 && (module->ssl == NULL || module->SSLConnect != 0))
{
module->OnSendOK(module, module->user);
if (module->Transport.SendOkPtr != NULL) { module->Transport.SendOkPtr(module); }

View File

@@ -45,7 +45,7 @@ void __fastcall util_md5hex(char* data, int datalen, char *out)
MD5_Update(&mdContext, (unsigned char *)data, datalen);
MD5_Final(digest, &mdContext);
for (i = 0; i < HALF_NONCE_SIZE; i++)
for (i = 0; i < sizeof(digest); i++)
{
*(temp++) = utils_HexTable2[(unsigned char)digest[i] >> 4];
*(temp++) = utils_HexTable2[(unsigned char)digest[i] & 0x0F];
@@ -61,7 +61,6 @@ void __fastcall util_sha1(char* data, int datalen, char* result)
SHA1_Final((unsigned char*)result, &c);
result[20] = 0;
}
void __fastcall util_sha256(char* data, int datalen, char* result)
{
SHA256_CTX c;
@@ -69,10 +68,17 @@ void __fastcall util_sha256(char* data, int datalen, char* result)
SHA256_Update(&c, data, datalen);
SHA256_Final((unsigned char*)result, &c);
}
int __fastcall util_sha256file(char* filename, char* result)
void __fastcall util_sha384(char* data, int datalen, char* result)
{
SHA512_CTX c;
SHA384_Init(&c);
SHA384_Update(&c, data, datalen);
SHA384_Final((unsigned char*)result, &c);
}
int __fastcall util_sha384file(char* filename, char* result)
{
FILE *pFile = NULL;
SHA256_CTX c;
SHA512_CTX c;
size_t len = 0;
char *buf = NULL;
@@ -83,14 +89,14 @@ int __fastcall util_sha256file(char* filename, char* result)
pFile = fopen(filename, "rb");
#endif
if (pFile == NULL) goto error;
SHA256_Init(&c);
SHA384_Init(&c);
if ((buf = (char*)malloc(4096)) == NULL) goto error;
while ((len = fread(buf, 1, 4096, pFile)) > 0) SHA256_Update(&c, buf, len);
while ((len = fread(buf, 1, 4096, pFile)) > 0) SHA384_Update(&c, buf, len);
free(buf);
buf = NULL;
fclose(pFile);
pFile = NULL;
SHA256_Final((unsigned char*)result, &c);
SHA384_Final((unsigned char*)result, &c);
return 0;
error:
@@ -608,7 +614,7 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i
{
// Computer the hash of the public key
//util_sha256((char*)x->cert_info->key->public_key->data, x->cert_info->key->public_key->length, hash); // OpenSSL 1.0
X509_pubkey_digest(x, EVP_sha256(), (unsigned char*)hash, (unsigned int*)&hashlen); // OpenSSL 1.1
X509_pubkey_digest(x, EVP_sha384(), (unsigned char*)hash, (unsigned int*)&hashlen); // OpenSSL 1.1
util_tohex(hash, UTIL_HASHSIZE, nameStr);
X509_NAME_add_entry_by_txt(cname, "CN", MBSTRING_ASC, (unsigned char*)nameStr, -1, -1, 0);
@@ -632,7 +638,7 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i
//util_add_ext(x, NID_netscape_cert_type, "sslCA");
//util_add_ext(x, NID_netscape_comment, "example comment extension");
if (!X509_sign(x, pk, EVP_sha256())) goto err;
if (!X509_sign(x, pk, EVP_sha384())) goto err;
}
else
{
@@ -662,7 +668,7 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i
X509_EXTENSION_free(ex);
}
if (!X509_sign(x, rootcert->pkey, EVP_sha256())) goto err;
if (!X509_sign(x, rootcert->pkey, EVP_sha384())) goto err;
}
cert->x509 = x;
@@ -679,7 +685,7 @@ int __fastcall util_keyhash(struct util_cert cert, char* result)
int hashlen = UTIL_HASHSIZE;
if (cert.x509 == NULL) return -1;
//util_sha256((char*)(cert.x509->cert_info->key->public_key->data), cert.x509->cert_info->key->public_key->length, result); // OpenSSL 1.0
X509_pubkey_digest(cert.x509, EVP_sha256(), (unsigned char*)result,(unsigned int *) &hashlen); // OpenSSL 1.1
X509_pubkey_digest(cert.x509, EVP_sha384(), (unsigned char*)result,(unsigned int *) &hashlen); // OpenSSL 1.1
return 0;
}
@@ -688,7 +694,7 @@ int __fastcall util_keyhash2(X509* cert, char* result)
int hashlen = UTIL_HASHSIZE;
if (cert == NULL) return -1;
//util_sha256((char*)(cert->cert_info->key->public_key->data), cert->cert_info->key->public_key->length, result); // OpenSSL 1.0
X509_pubkey_digest(cert, EVP_sha256(), (unsigned char*)result, (unsigned int*)&hashlen); // OpenSSL 1.1
X509_pubkey_digest(cert, EVP_sha384(), (unsigned char*)result, (unsigned int*)&hashlen); // OpenSSL 1.1
return 0;
}
@@ -703,7 +709,7 @@ int __fastcall util_sign(struct util_cert cert, char* data, int datalen, char**
if (datalen <= UTIL_HASHSIZE) return 0;
// Add hash of the certificate to start of data
X509_digest(cert.x509, EVP_sha256(), (unsigned char*)data, &hashsize);
X509_digest(cert.x509, EVP_sha384(), (unsigned char*)data, &hashsize);
// Sign the block
in = BIO_new_mem_buf(data, datalen);

View File

@@ -17,7 +17,8 @@ int __fastcall util_hexToint(char *hexString, int hexStringLength);
int __fastcall util_hexToBuf(char *hexString, int hexStringLength, char* output);
void __fastcall util_sha256(char* data, int datalen, char* result);
int __fastcall util_sha256file(char* filename, char* result);
void __fastcall util_sha384(char* data, int datalen, char* result);
int __fastcall util_sha384file(char* filename, char* result);
// File and data methods
size_t __fastcall util_writefile(char* filename, char* data, int datalen);
@@ -34,9 +35,8 @@ BOOL util_CopyFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _I
void __fastcall util_random(int length, char* result);
void __fastcall util_randomtext(int length, char* result);
#define UTIL_HASHSIZE 32
#define NONCE_SIZE 32
#define HALF_NONCE_SIZE 16
#define UTIL_HASHSIZE 48
#define NONCE_SIZE 48
#ifdef MICROSTACK_NOTLS
#include "md5.h"

View File

@@ -56,15 +56,6 @@ struct ILibMulticastSocket_StateModule
int AddressListLengthV4;
int* IndexListV6;
int IndexListLenV6;
// Sockets used to sent and receive messages
#if defined(WIN32) || defined(_WIN32_WCE)
SOCKET NOTIFY_SEND_socks;
SOCKET NOTIFY_SEND_socks6;
#else
int NOTIFY_SEND_socks;
int NOTIFY_SEND_socks6;
#endif
};
// Received a UDP packet on the IPv4 socket, process it.
@@ -219,43 +210,15 @@ void ILibMulticastSocket_BroadcastUdpPacketV4(struct ILibMulticastSocket_StateMo
if (localif == NULL || ((struct sockaddr_in*)localif)->sin_addr.s_addr == module->AddressListV4[i].sin_addr.s_addr)
#endif
{
if (module->NOTIFY_SEND_socks != 0)
#ifndef NACL
if (module->UDPServers[i] != NULL)
{
#if (!defined(_WIN32_WCE) || (defined(_WIN32_WCE) && _WIN32_WCE>=400)) && !defined(NACL)
setsockopt(module->NOTIFY_SEND_socks, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&(module->AddressListV4[i].sin_addr), sizeof(struct in_addr));
for (j = 0; j < count; j++) sendto(module->NOTIFY_SEND_socks, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
#else
for (j = 0; j < count; j++) sendto(module->NOTIFY_SEND_socks, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
#endif
socket = ILibAsyncUDPSocket_GetSocket(module->UDPServer);
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&(module->AddressListV4[i].sin_addr), sizeof(struct in_addr));
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&(module->TTL), sizeof(int));
for (j = 0; j < count; j++) sendto(socket, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
}
else
{
#if (!defined(_WIN32_WCE) || (defined(_WIN32_WCE) && _WIN32_WCE>=400)) && !defined(NACL)
if (module->UDPServers[i] != NULL)
{
socket = ILibAsyncUDPSocket_GetSocket(module->UDPServers[i]);
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&(module->AddressListV4[i].sin_addr), sizeof(struct in_addr));
for (j = 0; j < count; j++) sendto(socket, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
}
#else
for (j=0;j<count;j++) sendto(socket, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
#endif
}
}
}
if (i == 0)
{
if (module->NOTIFY_SEND_socks != 0)
{
struct in_addr tmp;
tmp.s_addr = addr->sin_addr.s_addr;
addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#if (!defined(_WIN32_WCE) || (defined(_WIN32_WCE) && _WIN32_WCE>=400)) && !defined(NACL)
for (j = 0; j < count; j++) sendto(module->NOTIFY_SEND_socks, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
#else
for (j = 0; j < count; j++) sendto(module->NOTIFY_SEND_socks, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
#endif
addr->sin_addr.s_addr = tmp.s_addr;
#endif
}
}
}
@@ -270,14 +233,11 @@ void ILibMulticastSocket_BroadcastUdpPacketV6(struct ILibMulticastSocket_StateMo
// TODO: Consider the local interface
UNREFERENCED_PARAMETER( localif );
if (module->NOTIFY_SEND_socks6 == 0) return;
for(i = 0; i < module->IndexListLenV6; i++)
{
#if (!defined(_WIN32_WCE) || (defined(_WIN32_WCE) && _WIN32_WCE>=400)) && !defined(NACL)
setsockopt(module->NOTIFY_SEND_socks6, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&(module->IndexListV6[i]), 4);
for (j=0;j<count;j++) sendto(module->NOTIFY_SEND_socks6, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in6));
#else
for (j=0;j<count;j++) sendto(module->NOTIFY_SEND_socks6, data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in6));
#ifndef NACL
setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&(module->IndexListV6[i]), 4);
for (j=0;j<count;j++) sendto(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), data, datalen, 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in6));
#endif
}
}
@@ -301,8 +261,8 @@ void ILibMulticastSocket_BroadcastIF(struct ILibMulticastSocket_StateModule *mod
// Perform unicast transmit using this socket.
int ILibMulticastSocket_Unicast(struct ILibMulticastSocket_StateModule *module, struct sockaddr* target, char* data, int datalen)
{
if (target->sa_family == AF_INET6) return sendto(module->NOTIFY_SEND_socks6, data, datalen, 0, target, INET_SOCKADDR_LENGTH(target->sa_family));
if (target->sa_family == AF_INET) return sendto(module->NOTIFY_SEND_socks, data, datalen, 0, target, INET_SOCKADDR_LENGTH(target->sa_family));
if (target->sa_family == AF_INET6) return sendto(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), data, datalen, 0, target, INET_SOCKADDR_LENGTH(target->sa_family));
if (target->sa_family == AF_INET) return sendto(ILibAsyncUDPSocket_GetSocket(module->UDPServer), data, datalen, 0, target, INET_SOCKADDR_LENGTH(target->sa_family));
return -1;
}
@@ -315,7 +275,6 @@ void ILibMulticastSocket_Destroy(void *object)
// Create a new MulticastSocket module. This module handles all send and receive traffic for IPv4 and IPv6 on a given multicast group.
struct ILibMulticastSocket_StateModule *ILibMulticastSocket_Create(void *Chain, int BufferSize, unsigned short LocalPort, struct sockaddr_in *MulticastAddr, struct sockaddr_in6 *MulticastAddr6, ILibAsyncUDPSocket_OnData OnData, void *user, int loopback)
{
int optval = 1;
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
struct ILibMulticastSocket_StateModule* module;
@@ -355,17 +314,13 @@ struct ILibMulticastSocket_StateModule *ILibMulticastSocket_Create(void *Chain,
module->UDPServer = ILibAsyncUDPSocket_CreateEx(Chain, 0, (struct sockaddr*)&addr4, ILibAsyncUDPSocket_Reuse_SHARED, UDPSocket_OnDataV4, NULL, module);
if (module->UDPServer == NULL) { free(module); PRINTERROR(); return NULL; }
// Set TTL, Reuse, Loop flags assumed to already be set
module->NOTIFY_SEND_socks = ILibAsyncUDPSocket_GetSocket(module->UDPServer);
#ifdef NACL
#else
if (setsockopt(module->NOTIFY_SEND_socks, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&(module->TTL), sizeof(int)) != 0) {ILIBCRITICALERREXIT(253);}
if (setsockopt(module->NOTIFY_SEND_socks, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&(module->Loopback), sizeof(int)) != 0) {ILIBCRITICALERREXIT(253);}
#ifndef NACL
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer), IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&(module->TTL), sizeof(int)) != 0) {ILIBCRITICALERREXIT(253);}
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer), IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&(module->Loopback), sizeof(int)) != 0) {ILIBCRITICALERREXIT(253);}
// Allow IPv4 Broadcast on this socket
if (setsockopt(module->NOTIFY_SEND_socks, SOL_SOCKET, SO_BROADCAST, (char*)&optval, 4) != 0) ILIBCRITICALERREXIT(253);
//if (setsockopt(module->NOTIFY_SEND_socks, SOL_SOCKET, SO_BROADCAST, (char*)&optval, 4) != 0) ILIBCRITICALERREXIT(253);
#endif
@@ -382,12 +337,9 @@ struct ILibMulticastSocket_StateModule *ILibMulticastSocket_Create(void *Chain,
if (module->MulticastAddr6.sin6_port == 0) module->MulticastAddr6.sin6_port = htons(LocalPort);
// Set TTL, IPv6, Loop and Reuse flags assumed to already be set
module->NOTIFY_SEND_socks6 = ILibAsyncUDPSocket_GetSocket(module->UDPServer6);
#ifdef NACL
#else
if (setsockopt(module->NOTIFY_SEND_socks6, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
if (setsockopt(module->NOTIFY_SEND_socks6, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const char*)&(module->Loopback), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#ifndef NACL
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const char*)&(module->Loopback), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#endif
}
}
@@ -407,8 +359,8 @@ void ILibSetTTL(void *vmodule, int ttl)
#ifdef NACL
#else
if (module->NOTIFY_SEND_socks != 0 && setsockopt(module->NOTIFY_SEND_socks, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
if (module->NOTIFY_SEND_socks6 != 0 && setsockopt(module->NOTIFY_SEND_socks6, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer), IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
if (setsockopt(ILibAsyncUDPSocket_GetSocket(module->UDPServer6), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&(module->TTL), sizeof(int)) != 0) ILIBCRITICALERREXIT(253);
#endif
}
@@ -435,7 +387,7 @@ void ILibMulticastSocket_WakeOnLan(void *module, char* mac)
for (i = 0; i < 2; i++)
{
// IPv4 Broadcast, works only in the same subnet
sendto(((struct ILibMulticastSocket_StateModule*)module)->NOTIFY_SEND_socks, ILibScratchPad, 102, 0, (const struct sockaddr*)&addr4, sizeof(struct sockaddr_in));
sendto(ILibAsyncUDPSocket_GetSocket(((struct ILibMulticastSocket_StateModule*)module)->UDPServer), ILibScratchPad, 102, 0, (const struct sockaddr*)&addr4, sizeof(struct sockaddr_in));
// IPv4 & IPv6 Multicast. Only works if the machine still is subscribed to SSDP messages (S1 or S3 usualy), but has out-of-subnet range.
ILibMulticastSocket_Broadcast((struct ILibMulticastSocket_StateModule*)module, ILibScratchPad, 102, 1);

View File

@@ -130,13 +130,13 @@ int dbg_GetCount()
return(malloc_counter);
}
unsigned long long ILibHTONLL(unsigned long long v)
uint64_t ILibHTONLL(uint64_t v)
{
{ union { unsigned long lv[2]; unsigned long long llv; } u; u.lv[0] = htonl(v >> 32); u.lv[1] = htonl(v & 0xFFFFFFFFULL); return u.llv; }
{ union { uint32_t lv[2]; uint64_t llv; } u; u.lv[0] = htonl(v >> 32); u.lv[1] = htonl(v & 0xFFFFFFFFULL); return u.llv; }
}
unsigned long long ILibNTOHLL(unsigned long long v)
uint64_t ILibNTOHLL(uint64_t v)
{
{ union { unsigned long lv[2]; unsigned long long llv; } u; u.llv = v; return ((unsigned long long)ntohl(u.lv[0]) << 32) | (unsigned long long)ntohl(u.lv[1]); }
{ union { uint32_t lv[2]; uint64_t llv; } u; u.llv = v; return ((uint64_t)ntohl(u.lv[0]) << 32) | (uint64_t)ntohl(u.lv[1]); }
}
//! Returns X where 2^X = Specified Integer
@@ -5024,6 +5024,7 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
int TempStringLength, TempStringLength2;
unsigned short lport;
char* laddr = NULL;
int laddrLen = 0;
ILibParseUriResult retVal = ILibParseUriResult_UNKNOWN_SCHEME;
@@ -5097,6 +5098,7 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
if ((laddr = (char*)malloc(TempStringLength2 + 2)) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(laddr, TempStringLength2 + 2, result3->FirstResult->data, TempStringLength2 + 1);
(laddr)[TempStringLength2 + 1] = '\0';
laddrLen = TempStringLength2 + 1;
}
}
else
@@ -5106,6 +5108,7 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
if ((laddr = (char*)malloc(TempStringLength2 + 1)) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(laddr, TempStringLength2 + 1, result3->FirstResult->data, TempStringLength2);
(laddr)[TempStringLength2] = '\0';
laddrLen = TempStringLength2;
}
// Cleanup
@@ -5121,8 +5124,25 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
if (laddr != NULL && laddr[0] == '[')
{
// IPv6
int pct = ILibString_LastIndexOf(laddr, laddrLen, "%", 1);
laddr[laddrLen - 1] = 0;
if (pct > 0)
{
laddr[pct] = 0;
pct = atoi(laddr + pct + 1);
}
else
{
pct = -1;
}
AddrStruct->sin6_family = AF_INET6;
ILibInet_pton(AF_INET6, laddr + 1, &(AddrStruct->sin6_addr));
if (pct >= 0)
{
AddrStruct->sin6_scope_id = pct;
}
AddrStruct->sin6_port = (unsigned short)htons(lport);
}
else
@@ -5205,12 +5225,15 @@ struct packetheader* ILibClonePacket(struct packetheader *packet)
n = packet->FirstField;
while (n!=NULL)
{
ILibAddHeaderLine(
RetVal,
n->Field,
n->FieldLength,
n->FieldData,
n->FieldDataLength);
if (ILibHasEntry(packet->HeaderTable, n->Field, n->FieldLength) != 0)
{
ILibAddHeaderLine(
RetVal,
n->Field,
n->FieldLength,
n->FieldData,
n->FieldDataLength);
}
n = n->NextField;
}
return RetVal;
@@ -8560,7 +8583,7 @@ char* ILibInet_ntop2(struct sockaddr* addr, char *dst, size_t dstsize)
ILibInet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr, dst, dstsize);
if (((struct sockaddr_in6*)addr)->sin6_scope_id != 0)
{
int dstLen = strnlen_s(dst, dstsize);
int dstLen = (int)strnlen_s(dst, dstsize);
sprintf_s(dst + dstLen, dstsize - dstLen, "%%%u", ((struct sockaddr_in6*)addr)->sin6_scope_id);
}
return(dst);
@@ -8695,6 +8718,17 @@ int ILibResolveEx3(char* hostname, char *service, struct sockaddr_in6* addr6, in
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
#ifndef WIN32
if (hostname[0] == '[')
{
int hostnameLen = strnlen_s(hostname, 4096);
char *newHost = alloca(hostnameLen);
memcpy_s(newHost, hostnameLen, hostname + 1, hostnameLen - 2);
newHost[hostnameLen - 2] = 0;
hostname = newHost;
}
#endif
r = getaddrinfo(hostname, service, &hints, &result);
if (r != 0) { if (result != NULL) { freeaddrinfo(result); } return r; }
if (result == NULL) return -1;

View File

@@ -360,8 +360,8 @@ int ILibIsRunningOnChainThread(void* chain);
char* ILibTime_Serialize(time_t timeVal);
long long ILibGetUptime();
unsigned long long ILibHTONLL(unsigned long long v);
unsigned long long ILibNTOHLL(unsigned long long v);
uint64_t ILibHTONLL(uint64_t v);
uint64_t ILibNTOHLL(uint64_t v);
typedef void* ILibReaderWriterLock;
ILibReaderWriterLock ILibReaderWriterLock_Create();

View File

@@ -18,6 +18,9 @@ limitations under the License.
#include "ILibCrypto.h"
#ifndef WIN32
#include <sys/file.h>
#include <unistd.h>
#else
#include <io.h>
#endif
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
@@ -25,7 +28,8 @@ limitations under the License.
#include <crtdbg.h>
#endif
#define SHA256HASHSIZE 32
#define SHA384HASHSIZE 48
#ifdef _WIN64
#define ILibSimpleDataStore_GetPosition(filePtr) _ftelli64(filePtr)
@@ -52,7 +56,7 @@ typedef struct ILibSimpleDataStore_Root
4 Bytes - Node size
4 Bytes - Key length
4 Bytes - Value length
32 Bytes - SHA256 hash check value
48 Bytes - SHA384 hash check value
Variable - Key
Variable - Value
------------------------------------------ */
@@ -62,7 +66,7 @@ typedef struct ILibSimpleDataStore_RecordHeader
int nodeSize;
int keyLen;
int valueLength;
char hash[SHA256HASHSIZE];
char hash[SHA384HASHSIZE];
} ILibSimpleDataStore_RecordHeader;
typedef struct ILibSimpleDataStore_RecordNode
@@ -70,7 +74,7 @@ typedef struct ILibSimpleDataStore_RecordNode
int nodeSize;
int keyLen;
int valueLength;
char valueHash[SHA256HASHSIZE];
char valueHash[SHA384HASHSIZE];
DS_Long valueOffset;
char key[];
} ILibSimpleDataStore_RecordNode;
@@ -78,14 +82,14 @@ typedef struct ILibSimpleDataStore_RecordNode
typedef struct ILibSimpleDataStore_TableEntry
{
int valueLength;
char valueHash[SHA256HASHSIZE];
char valueHash[SHA384HASHSIZE];
DS_Long valueOffset;
} ILibSimpleDataStore_TableEntry;
const int ILibMemory_SimpleDataStore_CONTAINERSIZE = sizeof(ILibSimpleDataStore_Root);
// Perform a SHA256 hash of some data
void ILibSimpleDataStore_SHA256(char *data, int datalen, char* result) { util_sha256(data, datalen, result); }
// Perform a SHA384 hash of some data
void ILibSimpleDataStore_SHA384(char *data, int datalen, char* result) { util_sha384(data, datalen, result); }
// Write a key/value pair to file, the hash is already calculated
DS_Long ILibSimpleDataStore_WriteRecord(FILE *f, char* key, int keyLen, char* value, int valueLen, char* hash)
@@ -98,7 +102,7 @@ DS_Long ILibSimpleDataStore_WriteRecord(FILE *f, char* key, int keyLen, char* va
header->nodeSize = htonl(sizeof(ILibSimpleDataStore_RecordNode) + keyLen + valueLen);
header->keyLen = htonl(keyLen);
header->valueLength = htonl(valueLen);
if (hash != NULL) { memcpy_s(header->hash, sizeof(header->hash), hash, SHA256HASHSIZE); } else { memset(header->hash, 0, SHA256HASHSIZE); }
if (hash != NULL) { memcpy_s(header->hash, sizeof(header->hash), hash, SHA384HASHSIZE); } else { memset(header->hash, 0, SHA384HASHSIZE); }
if (fwrite(headerBytes, 1, sizeof(ILibSimpleDataStore_RecordNode), f)) {}
if (fwrite(key, 1, keyLen, f)) {}
@@ -111,9 +115,9 @@ DS_Long ILibSimpleDataStore_WriteRecord(FILE *f, char* key, int keyLen, char* va
// Read the next record in the file
ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDataStore_Root *root)
{
SHA256_CTX c;
SHA512_CTX c;
char data[4096];
char result[SHA256HASHSIZE];
char result[SHA384HASHSIZE];
int i, bytesLeft;
ILibSimpleDataStore_RecordNode *node = (ILibSimpleDataStore_RecordNode*)(root->scratchPad );
@@ -137,28 +141,25 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
// Validate Data, in 4k chunks at a time
bytesLeft = node->valueLength;
// Hash SHA256 the data
SHA256_Init(&c);
// Hash SHA384 the data
SHA384_Init(&c);
while (bytesLeft > 0)
{
i = (int)fread(data, 1, bytesLeft > 4096 ? 4096 : bytesLeft, root->dataFile);
if (i <= 0) { bytesLeft = 0; break; }
SHA256_Update(&c, data, i);
SHA384_Update(&c, data, i);
bytesLeft -= i;
}
SHA256_Final((unsigned char*)result, &c);
SHA384_Final((unsigned char*)result, &c);
if (node->valueLength > 0)
{
// Check the hash
if (memcmp(node->valueHash, result, SHA256HASHSIZE) == 0) {
if (memcmp(node->valueHash, result, SHA384HASHSIZE) == 0) {
return node; // Data is correct
}
return NULL; // Data is corrupt
}
else
{
return(node);
}
return node;
}
// ???
@@ -192,7 +193,7 @@ void ILibSimpleDataStore_RebuildKeyTable(ILibSimpleDataStore_Root *root)
{
// If the value is not empty, we need to create/overwrite this value in memory
if (entry == NULL) { entry = (ILibSimpleDataStore_TableEntry*)ILibMemory_Allocate(sizeof(ILibSimpleDataStore_TableEntry), 0, NULL, NULL); }
memcpy_s(entry->valueHash, sizeof(entry->valueHash), node->valueHash, SHA256HASHSIZE);
memcpy_s(entry->valueHash, sizeof(entry->valueHash), node->valueHash, SHA384HASHSIZE);
entry->valueLength = node->valueLength;
entry->valueOffset = node->valueOffset;
ILibHashtable_Put(root->keyTable, NULL, node->key, node->keyLen, entry);
@@ -231,6 +232,14 @@ FILE* ILibSimpleDataStore_OpenFileEx(char* filePath, int forceTruncateIfNonZero)
}
#define ILibSimpleDataStore_OpenFile(filePath) ILibSimpleDataStore_OpenFileEx(filePath, 0)
int ILibSimpleDataStore_Exists(char *filePath)
{
#ifdef WIN32
return(_access(filePath, 0) == 0 ? 1 : 0);
#else
return(access(filePath, 0) == 0 ? 1 : 0);
#endif
}
// Open the data store file. Optionally allocate spare user memory
__EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx(char* filePath, int userExtraMemorySize)
{
@@ -265,19 +274,19 @@ __EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore)
// Store a key/value pair in the data store
__EXPORT_TYPE int ILibSimpleDataStore_PutEx(ILibSimpleDataStore dataStore, char* key, int keyLen, char* value, int valueLen)
{
char hash[SHA256HASHSIZE];
char hash[SHA384HASHSIZE];
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
ILibSimpleDataStore_SHA256(value, valueLen, hash); // Hash the value
ILibSimpleDataStore_SHA384(value, valueLen, hash); // Hash the value
// Create a new record for the key and value
if (entry == NULL) {
entry = (ILibSimpleDataStore_TableEntry*)ILibMemory_Allocate(sizeof(ILibSimpleDataStore_TableEntry), 0, NULL, NULL); }
else {
if (memcmp(entry->valueHash, hash, SHA256HASHSIZE) == 0) { return 0; }
if (memcmp(entry->valueHash, hash, SHA384HASHSIZE) == 0) { return 0; }
}
memcpy_s(entry->valueHash, sizeof(entry->valueHash), hash, SHA256HASHSIZE);
memcpy_s(entry->valueHash, sizeof(entry->valueHash), hash, SHA384HASHSIZE);
entry->valueLength = valueLen;
entry->valueOffset = ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, value, valueLen, entry->valueHash); // Write the key and value
root->fileSize = ILibSimpleDataStore_GetPosition(root->dataFile); // Update the size of the data store;
@@ -289,7 +298,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_PutEx(ILibSimpleDataStore dataStore, char*
// Get a value from the data store given a key
__EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char* key, int keyLen, char *buffer, int bufferLen)
{
char hash[32];
char hash[SHA384HASHSIZE];
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
@@ -298,14 +307,14 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char*
{
if (ILibSimpleDataStore_SeekPosition(root->dataFile, entry->valueOffset, SEEK_SET) != 0) return 0; // Seek to the position of the value in the data store
if (fread(buffer, 1, entry->valueLength, root->dataFile) == 0) return 0; // Read the value into the buffer
util_sha256(buffer, entry->valueLength, hash); // Compute the hash of the read value
if (memcmp(hash, entry->valueHash, SHA256HASHSIZE) != 0) return 0; // Check the hash, return 0 if not valid
util_sha384(buffer, entry->valueLength, hash); // Compute the hash of the read value
if (memcmp(hash, entry->valueHash, SHA384HASHSIZE) != 0) return 0; // Check the hash, return 0 if not valid
if (bufferLen > entry->valueLength) { buffer[entry->valueLength] = 0; } // Add a zero at the end to be nice, if the buffer can take it.
}
return entry->valueLength;
}
// Get the reference to the SHA256 hash value from the datastore for a given a key.
// Get the reference to the SHA384 hash value from the datastore for a given a key.
__EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
{
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;

View File

@@ -44,6 +44,9 @@ typedef void(*ILibSimpleDataStore_KeyEnumerationHandler)(ILibSimpleDataStore sen
__EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx(char* filePath, int userExtraMemorySize);
#define ILibSimpleDataStore_Create(filePath) ILibSimpleDataStore_CreateEx(filePath, 0)
// Check if the data store exists
int ILibSimpleDataStore_Exists(char *filePath);
// Close the data store.
__EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore);

View File

@@ -201,6 +201,7 @@ struct ILibWebClient_ChunkData
typedef struct ILibWebClientDataObject
{
int IsWebSocket;
int IsOrphan;
int PipelineFlag;
int ActivityCounter;
struct sockaddr_in6 remote;
@@ -680,6 +681,12 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
// Only continue if this is a client calling this
if (wcdo->Server != 0) return;
if (wcdo->IsOrphan != 0)
{
ILibWebClient_DestroyWebClientDataObject(wcdo);
return;
}
// The current request was cancelled, so it can't really be finished, so we
// need to skip this, because otherwise we will end up duplicating some calls.
@@ -2205,22 +2212,29 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
ILibWebClient_DestroyWebRequest(wr);
}
}
ILibWebClient_FinishedResponse(socketModule,wcdo);
SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect", 7, wcdo->Parent);)
sem_wait(&(wcdo->Parent->QLock));
wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect", 8, wcdo->Parent);)
sem_post(&(wcdo->Parent->QLock));
if (wr == NULL)
{
if (wcdo->IsWebSocket != 0)
{
// This was a websocket, so we must destroy the WCDO object, because it won't be destroyed anywhere else
ILibWebClient_DestroyWebClientDataObject(wcdo);
}
return;
if (wcdo->IsOrphan != 0 || wcdo->IsWebSocket != 0)
{
ILibWebClient_FinishedResponse(socketModule, wcdo);
return;
}
else
{
ILibWebClient_FinishedResponse(socketModule, wcdo);
}
//SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect", 7, wcdo->Parent);)
//sem_wait(&(wcdo->Parent->QLock));
//wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
//SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect", 8, wcdo->Parent);)
//sem_post(&(wcdo->Parent->QLock));
//if (wr == NULL)
//{
// if (wcdo->IsWebSocket != 0)
// {
// // This was a websocket, so we must destroy the WCDO object, because it won't be destroyed anywhere else
// ILibWebClient_DestroyWebClientDataObject(wcdo);
// }
// return;
//}
}
// Make Another Connection and Continue
@@ -2233,7 +2247,7 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
void ILibWebClient_OnInterrupt(ILibAsyncSocket_SocketModule socketModule, void *user)
{
struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)user;
if (wcdo->IsWebSocket != 0)
if (wcdo->IsWebSocket != 0 || wcdo->IsOrphan != 0)
{
ILibWebClient_DestroyWebClientDataObject(wcdo);
}
@@ -2570,6 +2584,7 @@ ILibWebClient_RequestToken ILibWebClient_PipelineRequest(
// We need to remove our WCDO from the DataTable, because this WCDO will no longer service HTTP requests
// after it is converted into a WebSocket. If we remove it from this table, then a future web request will create a new WCDO object
ILibDeleteEntry(wcm->DataTable, requestToken, tokenLength);
wcdo->IsOrphan = 1;
//ILibHashtable_Put(wcm->WebSocketTable, NULL, (char*)&wcdo, sizeof(void*), wcdo);
break;
}
@@ -3154,6 +3169,16 @@ void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok)
wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
if (wr != NULL) { return(&(wr->user1)); } else { return(NULL); }
}
void **ILibWebClient_RequestToken_GetUserObjects_Tail(ILibWebClient_RequestToken tok)
{
struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(tok);
struct ILibWebRequest *wr;
if (wcdo == NULL) return(NULL);
wr = (struct ILibWebRequest*)ILibQueue_PeekTail(wcdo->RequestQueue);
if (wr != NULL) { return(&(wr->user1)); }
else { return(NULL); }
}
/*! \fn ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token)
\brief Obtain the user object that was associated with a request, from the request token
@@ -3212,7 +3237,7 @@ ILibTransport_DoneState ILibWebClient_StreamRequestBody(
char hex[16];
int hexLen;
ILibTransport_DoneState result = ILibTransport_DoneState_ERROR;
ILibTransport_DoneState result = ILibTransport_DoneState_INCOMPLETE;
if (t != NULL && t->wcdo != NULL)
{

View File

@@ -241,6 +241,7 @@ void ILibWebClient_ResetUserObjects(ILibWebClient_StateObject webstate, void *us
ILibWebClient_RequestToken ILibWebClient_GetRequestToken_FromStateObject(ILibWebClient_StateObject WebStateObject);
ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token);
void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok);
void **ILibWebClient_RequestToken_GetUserObjects_Tail(ILibWebClient_RequestToken tok);
void ILibWebClient_Parse_ContentRange(char *contentRange, int *Start, int *End, int *TotalLength);
enum ILibWebClient_Range_Result ILibWebClient_Parse_Range(char *Range, long *Start, long *Length, long TotalLength);