1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-10 13:23:41 +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

@@ -1,14 +1,39 @@
var http = require('http');
var agent = require('MeshAgent');
var server = "";
var req = "";
var gtunnel = "";
var digest = require('http-digest').create("bryan", "roe");
agent.on('Connected', function (connectState)
console.log("Starting Digest Test (Agent Connected)");
//server = http.createServer({ "MeshAgent": agent, "requestCert": true, "checkClientIdentity": onVerifyClient }, OnRequest);
server = http.createServer(OnRequest);
server.listen(9093);
server.on('upgrade', OnServerUpgrade);
function OnServerUpgrade(imsg, sck, head)
{
console.log("Connection State = " + connectState.toString());
console.log("Connected: " + this.ServerUrl);
if(imsg.Digest_IsAuthenticated('www.meshcentral.com')==1)
{
var uname = imsg.Digest_GetUsername();
console.log("Digest Username was: " + uname);
if(uname == 'bryan' && imsg.Digest_ValidatePassword('roe')==1)
{
sck.upgradeWebSocket();
}
else
{
console.log("Bad Username/Password");
sck.end();
}
}
else
{
console.log("Sending Unauthorized");
imsg.Digest_SendUnauthorized('www.meshcentral.com', 'oops');
}
}
//gtunnel = require('global-tunnel');
//gtunnel.initialize({ host: "proxy.jf.intel.com", port: 911 });
@@ -25,11 +50,12 @@ agent.on('Connected', function (connectState)
digest.http = require('http');
//digest.get("http://127.0.0.1:9093/", function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
//digest.request({ protocol: "http:", method: "GET", host: "127.0.0.1", path: "/", port: 9093 }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); }).end();
var req = digest.request({ MeshAgent: agent, protocol: "wss:", method: "GET", host: "127.0.0.1", path: "/", port: 9093, checkServerIdentity:onVerifyServer }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
var req = digest.request({ protocol: "ws:", method: "GET", host: "127.0.0.1", path: "/", port: 9093 }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
req.on('upgrade', function (res, sk, h) { console.log("Upgraded to WebSocket!"); });
req.on('error', function () { console.log("Error occured"); });
req.end();
});
function OnAlt(imsg)
{
@@ -39,17 +65,7 @@ function OnGoogle(imsg)
{
console.log("Response Code = " + imsg.statusCode);
}
agent.Ready = function()
{
console.log("Starting Digest Test (Agent Connected)");
//server = http.createServer({ "MeshAgent": agent, "requestCert": true, "checkClientIdentity": onVerifyClient }, OnRequest);
server = http.createServer({ "MeshAgent": agent }, OnRequest);
server.listen(9093);
//req = http.request({ "protocol":"ws:", "hostname": "127.0.0.1", "port": 9093, "method": "GET", "path": "/", "MeshAgent": agent }, OnResponse);
//req.upgrade = OnWebSocket;
//req.end();
}
function OnWebSocket(msg, s, head)
{

121
Debug/PostDigest.js Normal file
View File

@@ -0,0 +1,121 @@
var http = require('http');
var server = "";
var req = "";
var gtunnel = "";
var digest = require('http-digest').create("bryan", "roe");
console.log("Starting POST Digest Test");
server = http.createServer(OnRequest);
server.listen(9093);
server.on('upgrade', OnServerUpgrade);
server.on('checkContinue', OnCheckContinue);
//server.on('checkContinue', OnCheckContinue_NoDigest);
digest.http = require('http');
//var req = digest.request({ protocol: "ws:", method: "GET", host: "127.0.0.1", path: "/", port: 9093 }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
//var req = http.request({ protocol: "http:", method: "POST", host: "127.0.0.1", path: "/", port: 9093, headers: { Expect: '100-Continue' } }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
var req = digest.request({ protocol: "http:", method: "POST", host: "127.0.0.1", path: "/", port: 9093, headers: { Expect: '100-Continue' } }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
req.on('upgrade', function (res, sk, h) { console.log("Upgraded to WebSocket!"); });
req.on('error', function () { console.log("Error occured"); });
req.on('continue', function () { console.log("Received Continue"); this.write("test"); this.end(); });
function OnCheckContinue(imsg, resp)
{
console.log("Recevied: Expect-100 Continue");
if (imsg.Digest_IsAuthenticated('www.meshcentral.com') == 1)
{
var uname = imsg.Digest_GetUsername();
console.log("Digest Username was: " + uname);
if (uname == 'bryan' && imsg.Digest_ValidatePassword('roe') == 1)
{
console.log("Validated");
imsg.on('data', function (chunk) { console.log('Received: ' + chunk.toString()); });
imsg.on('end', function () { console.log('Received Complete'); });
resp.writeContinue();
}
else
{
console.log("Bad Username/Password");
resp.statusCode = "500";
resp.statusMessage = "Error";
resp.end();
}
}
else
{
console.log("Sending Unauthorized");
imsg.Digest_SendUnauthorized('www.meshcentral.com', 'oops');
}
}
function OnCheckContinue_NoDigest(imsg, resp)
{
console.log("Recevied: Expect-100 Continue");
imsg.on('data', function (chunk) { console.log('Received: ' + chunk.toString()); });
imsg.on('end', function () { console.log('Received Complete'); });
resp.writeContinue();
}
function OnServerUpgrade(imsg, sck, head)
{
if(imsg.Digest_IsAuthenticated('www.meshcentral.com')==1)
{
var uname = imsg.Digest_GetUsername();
console.log("Digest Username was: " + uname);
if(uname == 'bryan' && imsg.Digest_ValidatePassword('roe')==1)
{
console.log("Upgrading to WebSocket");
sck.upgradeWebSocket();
}
else
{
console.log("Bad Username/Password");
sck.end();
}
}
else
{
console.log("Sending Unauthorized");
imsg.Digest_SendUnauthorized('www.meshcentral.com', 'oops');
}
}
function onVerifyServer(clientName, certs) {
console.log("Server Name = " + clientName + "\n");
for (var i = 0; i < certs.length; ++i) {
console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
}
//throw ("Not Valid");
}
function onVerifyClient(clientName, certs)
{
console.log("Client Name = " + clientName + "\n");
for (var i = 0; i < certs.length; ++i) {
console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
}
//throw ("Not Valid");
}
function onVerify(serverName, certs)
{
console.log("ServerName = " + serverName + "\n");
for (var i = 0; i < certs.length;++i)
{
console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
}
//throw ("Not Valid");
}
function OnRequest(req, res)
{
console.log("Received Request for: " + req.url);
}

120
Debug/WebRTC_Test2.html Normal file
View File

@@ -0,0 +1,120 @@
<html>
<head>
<title>WebRTC Test Application</title>
</head>
<body onload="start()">
<span id="statustext"></span>
<script type="text/javascript">
var configuration = { "iceServers": [] };
var connection = null;
var datachannel = null;
var currentanswer = null;
var wsocket = null;
var decoder = new TextDecoder('utf-8');
var sdp = null;
function start()
{
debug("Connecting signaling channel...");
wsocket = new WebSocket("ws://127.0.0.1:8585/control");
wsocket.binaryType = "arraybuffer";
wsocket.onopen = function (evt)
{
debug("Web Socket Connection established...");
startWebRTC();
}
wsocket.onmessage = function (evt)
{
//var cmd = JSON.parse(decoder.decode(new Uint8Array(evt.data)));
var cmd = JSON.parse(evt.data);
if (cmd.cmd == 'offer')
{
debug("Received WebRTC Offer...");
var ax = null;
if (typeof mozRTCSessionDescription !== 'undefined') { ax = new mozRTCSessionDescription({ type: "answer", sdp: cmd.data }) } else { ax = new RTCSessionDescription({ type: "answer", sdp: cmd.data }) }
connection.setRemoteDescription(ax, onSetRemoteDescriptionDone, onError);
}
}
}
function onSetRemoteDescriptionDone()
{
//connection.createAnswer(onAnswerDone, onError);
}
function onAnswerDone(answer)
{
//wsocket.send(JSON.stringify({ cmd: 'offer', data: answer.sdp }));
sdp = answer.sdp;
connection.setLocalDescription(answer, onSetLocalDescriptionDone, onError);
}
function startWebRTC()
{
debug("Initiating WebRTC...");
if (connection != null) { debug("Error!"); return; }
if (typeof mozRTCPeerConnection !== 'undefined') { connection = new mozRTCPeerConnection(configuration); }
else if (typeof RTCPeerConnection !== 'undefined') { connection = new RTCPeerConnection(configuration); }
else if (typeof webkitRTCPeerConnection !== 'undefined') { connection = new webkitRTCPeerConnection(configuration); }
else return false;
connection.ondatachannel = onDataChannel
connection.onicecandidate = onIceCandidate;
datachannel = connection.createDataChannel("browserDataChannel", {});
datachannel.onmessage = function (event) { debug("Remote: " + event.data); };
datachannel.onopen = function () { debug("browserDataChannel Connected."); };
datachannel.onclose = function (event) { debug("DataChannel was closed by remote"); }
connection.createOffer(onOfferDone, onError, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
}
function onOfferDone(offer)
{
// debug(offer.sdp);
currentoffer = offer;
connection.setLocalDescription(offer, onSetLocalDescriptionDone, onError);
sdp = currentoffer.sdp;
}
function onDataChannel(event)
{
debug("Data Channel ("+ event.channel.label + ") connected");
datachannel = event.channel;
datachannel.binaryType = "arraybuffer";
datachannel.onmessage = function (msg)
{
try
{
datachannel.send(msg.data.byteLength.toString());
}
catch(e)
{
debug(e.toString());
debug(msg.data.toString());
}
};
}
function onIceCandidate(e)
{
if (e.candidate == null) {
if (sdp == null) { debug('error'); return; }
wsocket.send(JSON.stringify({ cmd: 'offer', data: sdp }));
}
else
{
sdp += ("a=" + e.candidate.candidate + "\r\n");
}
}
function onSetLocalDescriptionDone() { }
function onError(e) { if (e.message) debug(e.message); else debug(e); }
function debug(msg) { document.getElementById("statustext").innerHTML += (msg + "\r\n"); }
</script>
</body>
</html>

134
Debug/WebRTC_Test2.js Normal file
View File

@@ -0,0 +1,134 @@
var http = require('http');
var rtc = require('ILibWebRTC');
var peerConnection;
var signalingChannel;
var dc;
var webServer = http.createServer(OnLocalWebRequest);
var processMgr = require('ILibProcessPipe');
var p;
webServer.on('upgrade', OnUpgrade);
webServer.listen(8585);
//p = processMgr.CreateProcess("c:\\windows\\system32\\cmd.exe", "/c", "start", "http://localhost:8585/start.html");
function OnUpgrade(imsg, sck, head)
{
console.log("WebSocket Connected");
signalingChannel = sck.upgradeWebSocket();
signalingChannel.on('data', OnSignalData);
peerConnection = rtc.createConnection();
peerConnection.on('connected', OnWebRTC_Connected);
peerConnection.on('dataChannel', OnWebRTC_DataChannel);
//console.log("Generating WebRTC Offer...");
//signalingChannel.write({ cmd: "offer", data: peerConnection.generateOffer() });
}
function OnSignalData(chunk)
{
var j = JSON.parse(chunk);
if (j.cmd == 'offer')
{
console.log("Received Offer");
signalingChannel.write({ cmd: "offer", data: peerConnection.setOffer(j.data) });
}
}
function OnLocalWebRequest(request, response)
{
if(request.method == 'GET' && request.url == '/start.html')
{
var fs = require('fs');
try
{
var stream = fs.createReadStream('WebRTC_Test2.html');
response.statusCode = 200;
response.statusMessage = "OK";
stream.pipe(response);
}
catch(e)
{
response.statusCode = 404;
response.statusMessage = "Not Found";
response.end();
}
}
else
{
response.statusCode = 404;
response.statusMessage = "Not Found";
response.end();
}
}
function OnWebRTC_Connected()
{
console.log("WebRTC Session Established");
//this.dc = this.createDataChannel("testChannel", OnTestChannel);
//if(mesh != null)
//{
// // Let create a data channel
// this.dc = this.createDataChannel("remoteDesktop", OnKVMChannel)
// this.tempTimeout = setTimeout(function (dc) { console.log("sending: 'test'"); dc.write("test"); }, 10000, this.dc);
//}
}
function OnTestChannel()
{
console.log("Successfully established Data Channel");
}
function OnKVMChannel()
{
console.log("Successfully established Data Channel to test Data throughput");
dc = this;
dc.kvm = mesh.getRemoteDesktopStream();
dc.on('data', function (buffer) { console.log("Peer Received: " + buffer.toString() + " bytes"); });
dc.on('end', function () { this.kvm.end(); console.log("Closing KVM Session"); });
dc.kvm.pipe(dc);
}
function OnWebRTC_DataChannel(dataChannel)
{
console.log("Data Channel (" + dataChannel.name + ") was created");
dc = dataChannel;
dc.on('data', function (buffer) { console.log("Received: " + buffer.length + " bytes"); dc.write(buffer.length.toString()); });
dc.on('end', function () { console.log("Data Channel: " + this.name + " was closed"); });
}
function OnTunnelData(buffer)
{
if (buffer == 'c')
{
console.log("Tunnel Established");
peerConnection = rtc.createConnection();
peerConnection.on('connected', OnWebRTC_Connected);
peerConnection.on('dataChannel', OnWebRTC_DataChannel);
if(mesh!=null)
{
console.log("Generating WebRTC Offer...");
this.write({ cmd: "offer", data: peerConnection.generateOffer() });
}
}
else
{
ProcessCommand(JSON.parse(buffer.toString()));
}
}
function ProcessCommand(cmd)
{
console.log("Received Command: " + cmd.cmd);
if(cmd.cmd == 'offer')
{
console.log("setting offer...");
console.log(cmd.data);
var counter = peerConnection.setOffer(cmd.data);
if(mesh == null)
{
signalingChannel.write({ cmd: "offer", data: counter });
}
}
if(cmd.cmd == 'candidate')
{
console.log("Received Candidate: " + cmd.data);
}
}

70
Debug/exe.js Normal file
View File

@@ -0,0 +1,70 @@
var fs = require('fs');
var exe;
var js;
var sz = new Buffer(8);
var exeLen = 0;
if (process.argv0.endsWith('.js'))
{
console.log("Non-integrated executable");
if (process.argv.length < 4)
{
console.log("Too few parameters!");
process.exit();
}
console.log("Executable Path: " + process.argv[1]);
console.log("JavaScript Path: " + process.argv[3]);
exe = fs.readFileSync(process.argv[1]);
w = fs.createWriteStream(process.argv[2], { flags: "wb" });
js = fs.readFileSync(process.argv[3]);
}
else
{
console.log("Integrated executable");
if (process.argv.length < 3)
{
console.log("Too few parameters!");
process.exit();
}
console.log("Executable Path: " + process.argv[0]);
console.log("JavaScript Path: " + process.argv[2]);
exe = fs.readFileSync(process.argv[0]);
w = fs.createWriteStream(process.argv[1], { flags: "wb" });
js = fs.readFileSync(process.argv[2]);
}
if (exe.readInt32BE(exe.length - 4) == exe.length)
{
console.log("Integrated JavaScript detected");
exeLen = exe.length - exe.readInt32BE(exe.length - 8) - 8;
console.log("Original Binary Size (Removed Integrated JavaScript): " + exeLen);
}
else
{
console.log("No integrated JavaScript detected");
exeLen = exe.length;
console.log("Original Binary Size: " + exeLen);
}
console.log("JavaScript Length: " + js.length);
w.write(exe.slice(0, exeLen), OnWroteExe);
function OnWroteExe()
{
this.write(js, function () {
sz.writeInt32BE(js.length, 0);
sz.writeInt32BE(exeLen + js.length + 8, 4);
this.write(sz, function () {
this.end();
console.log("Finished!");
process.exit();
});
});
}

View File

@@ -63,7 +63,46 @@ void BreakSink(int s)
int main(int argc, char **argv)
{
// Check if .JS file is integrated with executable
FILE *tmpFile;
char *integratedJavaScript = NULL;
int integratedJavaScriptLen = 0;
#ifdef WIN32
if (ILibString_EndsWith(argv[0], -1, ".exe", 4) == 0)
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", argv[0]);
tmpFile = fopen(ILibScratchPad, "rb");
}
else
{
tmpFile = fopen(argv[0], "rb");
}
#else
tmpFile = fopen(argv[0], "rb");
#endif
if (tmpFile != NULL)
{
fseek(tmpFile, 0, SEEK_END);
fseek(tmpFile, ftell(tmpFile) - 4, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
fseek(tmpFile, 0, SEEK_END);
if (ftell(tmpFile) == ntohl(((int*)ILibScratchPad)[0]))
{
fseek(tmpFile, ftell(tmpFile) - 8, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
integratedJavaScriptLen = ntohl(((int*)ILibScratchPad)[0]);
integratedJavaScript = ILibMemory_Allocate(1+integratedJavaScriptLen, 0, NULL, NULL);
fseek(tmpFile, 0, SEEK_END);
fseek(tmpFile, ftell(tmpFile) - 8 - integratedJavaScriptLen, SEEK_SET);
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
integratedJavaScript[integratedJavaScriptLen] = 0;
}
fclose(tmpFile);
}
int retCode = 0;
if (argc > 2 && memcmp(argv[1], "-faddr", 6) == 0)
{
uint64_t addrOffset;
@@ -73,6 +112,8 @@ int main(int argc, char **argv)
return(0);
}
if (integratedJavaScriptLen == 0)
{
if (argc >= 2 && strnlen_s(argv[1], 9) >= 8 && strncmp(argv[1], "-update:", 8) == 0)
{
/*
@@ -86,7 +127,7 @@ int main(int argc, char **argv)
MeshAgent_PerformSelfUpdate(argv[0], argv[1] + 8, argc, argv);
return 0;
}
}
#ifdef WIN32
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); // Set SIGNAL on windows to listen for Ctrl-C
@@ -110,6 +151,8 @@ int main(int argc, char **argv)
__try
{
agentHost = MeshAgent_Create();
agentHost->meshCoreCtx_embeddedScript = integratedJavaScript;
agentHost->meshCoreCtx_embeddedScriptLen = integratedJavaScriptLen;
while (MeshAgent_Start(agentHost, argc, argv) != 0);
retCode = agentHost->exitCode;
MeshAgent_Destroy(agentHost);
@@ -121,6 +164,8 @@ int main(int argc, char **argv)
_CrtDumpMemoryLeaks();
#else
agentHost = MeshAgent_Create();
agentHost->meshCoreCtx_embeddedScript = integratedJavaScript;
agentHost->meshCoreCtx_embeddedScriptLen = integratedJavaScriptLen;
while (MeshAgent_Start(agentHost, argc, argv) != 0);
retCode = agentHost->exitCode;
MeshAgent_Destroy(agentHost);

View File

@@ -109,6 +109,66 @@ typedef struct ScriptContainerSettings
void *nUncaughtExceptionUser;
char ContextGuid[sizeof(JS_ENGINE_CONTEXT) + 1];
}ScriptContainerSettings;
#pragma pack(push, 1)
typedef struct MeshCommand_BinaryPacket_AuthRequest
{
unsigned short command;
char serverHash[UTIL_HASHSIZE];
char serverNonce[UTIL_HASHSIZE];
}MeshCommand_BinaryPacket_AuthRequest;
typedef struct MeshCommand_BinaryPacket_AuthVerify_Header
{
unsigned short command;
unsigned short certLen;
char data[];
}MeshCommand_BinaryPacket_AuthVerify_Header;
typedef struct MeshCommand_BinaryPacket_AuthVerify
{
char *cert;
unsigned short certLen;
char *signature;
unsigned short signatureLen;
}MeshCommand_BinaryPacket_AuthVerify;
typedef enum MeshCommand_AuthInfo_PlatformType
{
MeshCommand_AuthInfo_PlatformType_DESKTOP = 1,
MeshCommand_AuthInfo_PlatformType_LAPTOP = 2,
MeshCommand_AuthInfo_PlatformType_MOBILE = 3,
MeshCommand_AuthInfo_PlatformType_SERVER = 4,
MeshCommand_AuthInfo_PlatformType_DISK = 5,
MeshCommand_AuthInfo_PlatformType_ROUTER = 6
}MeshCommand_BinaryPacket_AuthInfo_PlatformType;
typedef enum MeshCommand_AuthInfo_CapabilitiesMask
{
MeshCommand_AuthInfo_CapabilitiesMask_DESKTOP = 0x01,
MeshCommand_AuthInfo_CapabilitiesMask_TERMINAL = 0x02,
MeshCommand_AuthInfo_CapabilitiesMask_FILES = 0x04,
MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE = 0x08,
MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT= 0x10
}MeshCommand_AuthInfo_CapabilitiesMask;
typedef struct MeshCommand_BinaryPacket_AuthInfo
{
unsigned short command;
unsigned int infoVersion;
unsigned int agentId;
unsigned int agentVersion;
unsigned int platformType;
char MeshID[UTIL_HASHSIZE];
unsigned int capabilities;
unsigned short hostnameLen;
char hostname[];
}MeshCommand_BinaryPacket_AuthInfo;
typedef struct MeshCommand_BinaryPacket_CoreModule
{
unsigned short command;
unsigned short request;
char coreModuleHash[UTIL_HASHSIZE];
char coreModule[];
}MeshCommand_BinaryPacket_CoreModule;
#pragma pack(pop)
#define ScriptContainerSettingsKey "\xFF_ScriptContainerSettings"
ScriptContainerSettings* ScriptEngine_GetSettings(duk_context *ctx)
@@ -375,14 +435,14 @@ void UDPSocket_OnData(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer
// Check if this is a Mesh Server discovery packet and it is for our server
// It will have this form: "MeshCentral2|f5a50091028fe2c122434cbcbd2709a7ec10369295e5a0e43db8853a413d89df|wss://~:443/agent.ashx"
if ((bufferLength > 78) && (memcmp(buffer, "MeshCentral2|", 13) == 0) && ((ILibSimpleDataStore_Get(agentHost->masterDb, "ServerID", ILibScratchPad, sizeof(ILibScratchPad))) == 65) && (memcmp(ILibScratchPad, buffer + 13, 64) == 0)) {
if ((bufferLength > 78) && (memcmp(buffer, "MeshCentral2|", 13) == 0) && ((ILibSimpleDataStore_Get(agentHost->masterDb, "ServerID", ILibScratchPad, sizeof(ILibScratchPad))) == 97) && (memcmp(ILibScratchPad, buffer + 13, 96) == 0)) {
// We have a match, set the server URL correctly.
if (agentHost->multicastServerUrl != NULL) { free(agentHost->multicastServerUrl); agentHost->multicastServerUrl = NULL; }
if ((agentHost->multicastServerUrl = (char*)malloc(bufferLength - 78 + 128)) == NULL) { ILIBCRITICALEXIT(254); }
buffer[bufferLength] = 0;
ILibInet_ntop2((struct sockaddr*)remoteInterface, (char*)ILibScratchPad2, sizeof(ILibScratchPad));
sprintf_s(agentHost->multicastServerUrl, bufferLength - 78 + 128, buffer + 78, ILibScratchPad2);
sprintf_s(agentHost->multicastServerUrl, bufferLength - 78 + 128, buffer + 78 + 32, ILibScratchPad2);
//printf("FoundServer: %s\r\n", agentHost->multicastServerUrl);
if (agentHost->serverConnectionState == 0) { MeshServer_ConnectEx(agentHost); }
@@ -562,7 +622,7 @@ duk_ret_t ILibDuktape_MeshAgent_GenerateCertificate(duk_context *ctx)
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating JS TLS Certificate");
#endif
len = util_mkCert(NULL, &(cert), 2048, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL);
len = util_mkCert(NULL, &(cert), 3072, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL);
len = util_to_p12(cert, passphrase, &data);
duk_push_fixed_buffer(ctx, len);
@@ -1030,7 +1090,7 @@ int agent_GenerateCertificates(MeshAgentHostContainer *agent, char* certfile)
do
{
if (util_mkCert(NULL, &(agent->selfcert), 2048, 10000, "MeshNodeCertificate", CERTIFICATE_ROOT, NULL) == 0) return -1;
if (util_mkCert(NULL, &(agent->selfcert), 3072, 10000, "MeshNodeCertificate", CERTIFICATE_ROOT, NULL) == 0) return -1;
util_keyhash(agent->selfcert, agent->g_selfid);
} while (((int*)agent->g_selfid)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros.
@@ -1060,14 +1120,14 @@ int agent_GenerateCertificates(MeshAgentHostContainer *agent, char* certfile)
// Generate a new TLS certificate
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating TLS Certificate");
len = util_mkCert(&(agent->selfcert), &(agent->selftlscert), 2048, 10000, "localhost", CERTIFICATE_TLS_SERVER, NULL);
len = util_mkCert(&(agent->selfcert), &(agent->selftlscert), 3072, 10000, "localhost", CERTIFICATE_TLS_SERVER, NULL);
len = util_to_p12(agent->selftlscert, "hidden", &str);
ILibSimpleDataStore_PutEx(agent->masterDb, "SelfNodeTlsCert", 15, str, len);
util_free(str);
// Generate a new TLS client certificate
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating TLS Client Certificate");
len = util_mkCert(&(agent->selfcert), &(agent->selftlsclientcert), 2048, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL);
len = util_mkCert(&(agent->selfcert), &(agent->selftlsclientcert), 3072, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL);
len = util_to_p12(agent->selftlsclientcert, "hidden", &str);
ILibSimpleDataStore_PutEx(agent->masterDb, "SelfNodeTlsClientCert", 21, str, len);
util_free(str);
@@ -1291,96 +1351,107 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
switch (command)
{
case MeshCommand_AuthRequest: // This is basic authentication information from the server, we need to sign this and return the signature.
if (cmdLen == 66) {
int signLen, certlen;
SHA256_CTX c;
if (cmdLen == sizeof(MeshCommand_BinaryPacket_AuthRequest))
{
MeshCommand_BinaryPacket_AuthRequest *AuthRequest = (MeshCommand_BinaryPacket_AuthRequest*)cmd;
int signLen;
SHA512_CTX c;
EVP_PKEY *evp_prikey;
RSA *rsa_prikey;
char *certDer = ILibScratchPad2 + 4;
// Hash the server's web certificate and check if it matches the one in the auth request
util_keyhash2(peer, ILibScratchPad2); // Hash the server certificate public key and place it
if (memcmp(ILibScratchPad2, cmd + 2, UTIL_HASHSIZE) != 0) { printf("Bad server certificate hash\r\n"); break; } // TODO: Disconnect
memcpy_s(agent->serverNonce, sizeof(agent->serverNonce), cmd + 34, UTIL_HASHSIZE);
if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) { printf("Bad server certificate hash\r\n"); break; } // TODO: Disconnect
memcpy_s(agent->serverNonce, sizeof(agent->serverNonce), AuthRequest->serverNonce, sizeof(AuthRequest->serverNonce));
// Place our certificate in the response
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_AuthVerify); // MeshCommand_AuthVerify (2), agent certificate in ASN1 format
certlen = i2d_X509(agent->selfcert.x509, (unsigned char **)&certDer); // Place the agent root certificate in DER form
((unsigned short*)ILibScratchPad2)[1] = htons(certlen); // Place the size of the certificate
MeshCommand_BinaryPacket_AuthVerify_Header *rav = (MeshCommand_BinaryPacket_AuthVerify_Header*)ILibScratchPad2;
rav->command = htons(MeshCommand_AuthVerify); // MeshCommand_AuthVerify (2), agent certificate in ASN1 format
char *certDer = (char*)rav->data;
rav->certLen = htons(i2d_X509(agent->selfcert.x509, (unsigned char **)&certDer)); // Place the agent root certificate in DER form
// Use our agent root private key to sign the ServerWebHash + ServerNonce + AgentNonce
SHA256_Init(&c);
SHA384_Init(&c);
util_keyhash2(peer, ILibScratchPad);
SHA256_Update(&c, cmd + 2, UTIL_HASHSIZE); // Server web hash
SHA256_Update(&c, agent->serverNonce, UTIL_HASHSIZE); // Server nonce
SHA256_Update(&c, agent->agentNonce, UTIL_HASHSIZE); // Agent nonce
SHA256_Final((unsigned char*)ILibScratchPad, &c);
SHA384_Update(&c, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)); // Server web hash
SHA384_Update(&c, agent->serverNonce, UTIL_HASHSIZE); // Server nonce
SHA384_Update(&c, agent->agentNonce, UTIL_HASHSIZE); // Agent nonce
SHA384_Final((unsigned char*)ILibScratchPad, &c);
// Place the signature & send
evp_prikey = agent->selfcert.pkey;
rsa_prikey = EVP_PKEY_get1_RSA(evp_prikey);
signLen = 65535 - (4 + certlen);
if (RSA_sign(NID_sha256, (unsigned char*)ILibScratchPad, UTIL_HASHSIZE, (unsigned char*)(ILibScratchPad2 + 4 + certlen), (unsigned int*)&signLen, rsa_prikey) == 1)
signLen = sizeof(ILibScratchPad2) - sizeof(MeshCommand_BinaryPacket_AuthVerify_Header) - rav->certLen;
if (RSA_sign(NID_sha384, (unsigned char*)ILibScratchPad, UTIL_HASHSIZE, (unsigned char*)(rav->data + rav->certLen), (unsigned int*)&signLen, rsa_prikey) == 1)
{
// Signature succesful, send the result to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 4 + certlen + signLen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rav, sizeof(MeshCommand_BinaryPacket_AuthVerify_Header) + rav->certLen + signLen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
}
RSA_free(rsa_prikey);
}
break;
case MeshCommand_AuthVerify: // This is the signature from the server. We need to check everything is ok.
if (cmdLen > 8)
{
unsigned short certlen = ntohs(((unsigned short*)cmd)[1]);
if (cmdLen > (4 + certlen)) {
int platformType = 1, hashlen = UTIL_HASHSIZE;
SHA256_CTX c;
MeshCommand_BinaryPacket_AuthVerify_Header *avh = (MeshCommand_BinaryPacket_AuthVerify_Header*)cmd;
#ifdef WIN32
MeshCommand_BinaryPacket_AuthVerify *AuthVerify = (MeshCommand_BinaryPacket_AuthVerify*)_alloca(sizeof(MeshCommand_BinaryPacket_AuthVerify));
#else
MeshCommand_BinaryPacket_AuthVerify *AuthVerify = (MeshCommand_BinaryPacket_AuthVerify*)alloca(sizeof(MeshCommand_BinaryPacket_AuthVerify));
#endif
AuthVerify->cert = avh->data;
AuthVerify->certLen = ntohs(avh->certLen);
AuthVerify->signature = avh->data + AuthVerify->certLen;
AuthVerify->signatureLen = (unsigned short)(cmdLen - (int)(sizeof(MeshCommand_BinaryPacket_AuthVerify_Header) + AuthVerify->certLen));
if (cmdLen > (int)(sizeof(MeshCommand_BinaryPacket_AuthVerify_Header) + AuthVerify->certLen))
{
int hashlen = UTIL_HASHSIZE;
SHA512_CTX c;
X509* serverCert = NULL;
EVP_PKEY *evp_pubkey;
RSA *rsa_pubkey;
char* ptr = cmd + 4;
// Get the server certificate
if (!d2i_X509(&serverCert, (const unsigned char**)&ptr, certlen)) { printf("Invalid server certificate\r\n"); break; } // TODO: Disconnect
if (!d2i_X509(&serverCert, (const unsigned char**)&AuthVerify->cert, AuthVerify->certLen)) { printf("Invalid server certificate\r\n"); break; } // TODO: Disconnect
// Check if this certificate public key hash matches what we want
// util_sha256((char*)(serverCert->cert_info->key->public_key->data), serverCert->cert_info->key->public_key->length, ILibScratchPad); // OpenSSL 1.0
X509_pubkey_digest(serverCert, EVP_sha256(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1
X509_pubkey_digest(serverCert, EVP_sha384(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1
if (memcmp(ILibScratchPad, agent->serverHash, UTIL_HASHSIZE) != 0) { printf("Server certificate mismatch\r\n"); break; } // TODO: Disconnect
// Compute the authentication hash
SHA256_Init(&c);
SHA384_Init(&c);
util_keyhash2(peer, ILibScratchPad);
SHA256_Update(&c, ILibScratchPad, UTIL_HASHSIZE);
SHA256_Update(&c, agent->agentNonce, UTIL_HASHSIZE);
SHA256_Update(&c, agent->serverNonce, UTIL_HASHSIZE);
SHA256_Final((unsigned char*)ILibScratchPad, &c);
SHA384_Update(&c, ILibScratchPad, UTIL_HASHSIZE);
SHA384_Update(&c, agent->agentNonce, UTIL_HASHSIZE);
SHA384_Update(&c, agent->serverNonce, UTIL_HASHSIZE);
SHA384_Final((unsigned char*)ILibScratchPad, &c);
// Verify the hash signature using the server certificate
evp_pubkey = X509_get_pubkey(serverCert);
rsa_pubkey = EVP_PKEY_get1_RSA(evp_pubkey);
if (RSA_verify(NID_sha256, (unsigned char*)ILibScratchPad, UTIL_HASHSIZE, (unsigned char*)(cmd + 4 + certlen), cmdLen - (4 + certlen), rsa_pubkey) == 1)
if (RSA_verify(NID_sha384, (unsigned char*)ILibScratchPad, UTIL_HASHSIZE, (unsigned char*)AuthVerify->signature, AuthVerify->signatureLen, rsa_pubkey) == 1)
{
int hostnamelen = (int)strnlen_s(agent->hostname, sizeof(agent->hostname));
// Server signature verified, we are good to go.
agent->serverAuthState += 1;
// Send to the server information about this agent (TODO: Replace this with a struct)
if ((agent->batteryState != MeshAgentHost_BatteryInfo_NONE) && (agent->batteryState != MeshAgentHost_BatteryInfo_UNKNOWN)) { platformType = 2; } // If a battery is present, select laptop icon
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_AuthInfo); // MeshCommand_AuthInfo (3), agent information
((unsigned int*)(ILibScratchPad2 + 2))[0] = htonl(1); // Agent information version
((unsigned int*)(ILibScratchPad2 + 6))[0] = htonl(MESH_AGENTID); // Agent Identifier
((unsigned int*)(ILibScratchPad2 + 10))[0] = htonl(agent->version); // Agent Version
((unsigned int*)(ILibScratchPad2 + 14))[0] = htonl(platformType); // Platfrom Type: This is the icon: 1 = Desktop, 2 = Laptop, 3 = Mobile, 4 = Server, 5 = Disk, 6 = Router
memcpy_s(ILibScratchPad2 + 18, sizeof(ILibScratchPad2) - 18, agent->meshId, UTIL_HASHSIZE); // MeshId, taken from the agent settings
((unsigned int*)(ILibScratchPad2 + 50))[0] = htonl(8 + 16); // Capabilities of the agent(bitmask) : 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
((unsigned short*)ILibScratchPad2 + 54)[0] = htons(hostnamelen); // Hostname length
memcpy_s(ILibScratchPad2 + 56, sizeof(ILibScratchPad2) - 56, agent->hostname, hostnamelen); // Hostname
MeshCommand_BinaryPacket_AuthInfo *info = (MeshCommand_BinaryPacket_AuthInfo*)ILibScratchPad2;
info->command = htons(MeshCommand_AuthInfo);
info->infoVersion = htonl(1);
info->agentId = htonl(MESH_AGENTID);
info->agentVersion = htonl(agent->version);
info->platformType = htonl(((agent->batteryState != MeshAgentHost_BatteryInfo_NONE) && (agent->batteryState != MeshAgentHost_BatteryInfo_UNKNOWN)) ? MeshCommand_AuthInfo_PlatformType_LAPTOP : MeshCommand_AuthInfo_PlatformType_DESKTOP);
memcpy_s(info->MeshID, sizeof(info->MeshID), agent->meshId, sizeof(agent->meshId));
info->capabilities = htonl(MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE | MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT);
info->hostnameLen = htons(hostnamelen);
memcpy_s(info->hostname, sizeof(ILibScratchPad2) - sizeof(MeshCommand_BinaryPacket_AuthInfo), agent->hostname, hostnamelen);
// Send mesh agent information to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 56 + hostnamelen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)info, sizeof(MeshCommand_BinaryPacket_AuthInfo) + hostnamelen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
agent->retryTime = 0;
printf("Connected.\n");
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
@@ -1472,20 +1543,22 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
case MeshCommand_CoreModule: // New core modules to be used instead of the old one, if empty, remove the core module
{
char *coreException = NULL;
MeshCommand_BinaryPacket_CoreModule *cm = (MeshCommand_BinaryPacket_CoreModule*)cmd;
// If the agent is running with a local core, ignore this command
if (agent->localScript != 0) break;
if (cmdLen > 36) // Setup a new mesh core. Command is: cmdid + requestid + sha256hash + javascript
if (cmdLen > sizeof(MeshCommand_BinaryPacket_CoreModule)) // Setup a new mesh core.
{
char *hashref = ILibSimpleDataStore_GetHash(agent->masterDb, "CoreModule"); // Get the reference to the SHA256 hash for the currently running code
if (hashref == NULL || memcmp(hashref, cmd + 4, 32) != 0)
if (hashref == NULL || memcmp(hashref, cm->coreModuleHash, sizeof(cm->coreModuleHash)) != 0)
{
// If server sends us the same core, just do nothing.
// Server sent us a new core, start by storing it in the data store
ILibSimpleDataStore_PutEx(agent->masterDb, "CoreModule", 10, cmd + 36, cmdLen - 36); // Store the JavaScript in the data store
ILibSimpleDataStore_PutEx(agent->masterDb, "CoreModule", 10, cm->coreModule, cmdLen - sizeof(MeshCommand_BinaryPacket_CoreModule)); // Store the JavaScript in the data store
hashref = ILibSimpleDataStore_GetHash(agent->masterDb, "CoreModule"); // Get the reference to the SHA256 hash
if (memcmp(hashref, cmd + 4, 32) != 0) { // Check the hash for sanity
if (memcmp(hashref, cm->coreModuleHash, sizeof(cm->coreModuleHash)) != 0)
{ // Check the hash for sanity
// Something went wrong, clear the data store
ILibSimpleDataStore_Delete(agent->masterDb, "CoreModule");
@@ -1495,9 +1568,10 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
ScriptEngine_Stop(agent, MeshAgent_JavaCore_ContextGuid);
// Tell the server we are no longer running a core module
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
((unsigned short*)ILibScratchPad2)[1] = htons(requestid); // Request id
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 4, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
MeshCommand_BinaryPacket_CoreModule *rcm = (MeshCommand_BinaryPacket_CoreModule*)ILibScratchPad2;
rcm->command = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
rcm->request = htons(requestid); // Request id
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rcm, 4, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
break;
}
@@ -1506,7 +1580,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
//printf("CORE: Restart\r\n");
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
ILibRemoteLogging_Flags_VerbosityLevel_1, "MeshCore: Restart");
if ((coreException = ScriptEngine_Restart(agent, MeshAgent_JavaCore_ContextGuid, cmd + 40, cmdLen - 40)) != NULL)
if ((coreException = ScriptEngine_Restart(agent, MeshAgent_JavaCore_ContextGuid, cm->coreModule + 4, cmdLen - sizeof(MeshCommand_BinaryPacket_CoreModule) - 4)) != NULL)
{
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
ILibRemoteLogging_Flags_VerbosityLevel_1, "MeshCore: Error: %s", coreException);
@@ -1518,12 +1592,13 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
}
// Create the server confirmation message that we are running the new core
MeshCommand_BinaryPacket_CoreModule *rcm = (MeshCommand_BinaryPacket_CoreModule*)ILibScratchPad2;
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
((unsigned short*)ILibScratchPad2)[1] = htons(requestid); // Request id
memcpy_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, hashref, UTIL_HASHSIZE); // SHA256 hash
// Send the confirmation to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 36, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rcm, sizeof(MeshCommand_BinaryPacket_CoreModule), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
}
else if (cmdLen == 4)
{
@@ -1536,9 +1611,10 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
ScriptEngine_Stop(agent, MeshAgent_JavaCore_ContextGuid);
// Confirm to the server that we are not running any core
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
((unsigned short*)ILibScratchPad2)[1] = htons(requestid); // Request id
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 4, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
MeshCommand_BinaryPacket_CoreModule *rcm = (MeshCommand_BinaryPacket_CoreModule*)ILibScratchPad2;
rcm->command = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
rcm->request = htons(requestid); // Request id
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rcm, 4, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
}
break;
}
@@ -1552,12 +1628,13 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
if (agent->localScript != 0) break;
// Confirm to the server what core we are running
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
((unsigned short*)ILibScratchPad2)[1] = htons(requestid); // Request id
if (hashref != NULL) { memcpy_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, hashref, UTIL_HASHSIZE); len += 32; }
MeshCommand_BinaryPacket_CoreModule *rcm = (MeshCommand_BinaryPacket_CoreModule*)ILibScratchPad2;
rcm->command = htons(MeshCommand_CoreModuleHash); // MeshCommand_CoreModuleHash (11), SHA256 hash of the code module
rcm->request = htons(requestid); // Request id
if (hashref != NULL) { memcpy_s(rcm->coreModuleHash, sizeof(rcm->coreModuleHash), hashref, UTIL_HASHSIZE); len = sizeof(MeshCommand_BinaryPacket_CoreModule); }
// Send the confirmation to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, len, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rcm, len, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
break;
}
@@ -1567,12 +1644,13 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
// This is a request for the hash of the agent binary
// Built the response that includes our self hash
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_AgentHash); // MeshCommand_AgentHash (12), SHA256 hash of the agent executable
((unsigned short*)ILibScratchPad2)[1] = htons(requestid); // Request id
memcpy_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, agent->agentHash, UTIL_HASHSIZE);// SHA256 hash of the agent executable
MeshCommand_BinaryPacket_CoreModule *rcm = (MeshCommand_BinaryPacket_CoreModule*)ILibScratchPad2;
rcm->command = htons(MeshCommand_AgentHash); // MeshCommand_AgentHash (12), SHA256 hash of the agent executable
rcm->request = htons(requestid); // Request id
memcpy_s(rcm->coreModuleHash, sizeof(rcm->coreModuleHash), agent->agentHash, UTIL_HASHSIZE);// SHA256 hash of the agent executable
// Send the self hash back to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 36, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)rcm, sizeof(MeshCommand_BinaryPacket_CoreModule), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
break;
}
@@ -1583,15 +1661,18 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
#else
char* updateFilePath = MeshAgent_MakeAbsolutePath(agent->exePath, ".update");
#endif
char updateFileHash[32];
char updateFileHash[UTIL_HASHSIZE];
MeshCommand_BinaryPacket_CoreModule *cm = (MeshCommand_BinaryPacket_CoreModule*)cmd;
if (cmdLen == 4) {
// Indicates the start of the agent update transfer
util_deletefile(updateFilePath);
} else if (cmdLen == 36) {
} else if (cmdLen == sizeof(MeshCommand_BinaryPacket_CoreModule))
{
// Indicates the end of the agent update transfer
// Check the SHA256 hash of the received file against the file we got.
if ((util_sha256file(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cmd + 4, 32) == 0)) {
// Check the SHA384 hash of the received file against the file we got.
if ((util_sha384file(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
{
printf("UPDATE: End OK\r\n");
// Check the file signature & version number
//if (signcheck_verifysign(updateFilePath, 1))
@@ -1697,13 +1778,15 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
agent->serverConnectionState = 2;
// Start authentication by sending a auth nonce & server TLS cert hash.
// Send 256 bits SHA256 hash of TLS cert public key + 256 bits nonce
util_random(32, agent->agentNonce); // Generate a new mesh agent connection nonce
((unsigned short*)ILibScratchPad2)[0] = htons(MeshCommand_AuthRequest); // MeshCommand_AuthRequest (1), server hash + nonce
util_keyhash2(peer, ILibScratchPad2 + 2); // Hash the server certificate public key and place it
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
util_random(sizeof(agent->agentNonce), agent->agentNonce); // Generate a new mesh agent connection nonce
MeshCommand_BinaryPacket_AuthRequest *ar = (MeshCommand_BinaryPacket_AuthRequest*)ILibScratchPad2;
ar->command = htons(MeshCommand_AuthRequest); // MeshCommand_AuthRequest (1), server hash + nonce
util_keyhash2(peer, ar->serverHash); // Hash the server certificate public key and place it
if (peer != NULL) { X509_free(peer); }
memcpy_s(ILibScratchPad2 + 34, sizeof(ILibScratchPad2) - 34, agent->agentNonce, UTIL_HASHSIZE); // Place our mesh agent nonce
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, ILibScratchPad2, 66, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
memcpy_s(ar->serverNonce, sizeof(ar->serverNonce), agent->agentNonce, sizeof(agent->agentNonce)); // Place our mesh agent nonce
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)ar, sizeof(MeshCommand_BinaryPacket_AuthRequest), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
#endif
break;
}
@@ -1812,10 +1895,10 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
{
if (agent->multicastServerUrl != NULL) {
serverUrl = agent->multicastServerUrl;
serverUrlLen = strlen(serverUrl);
serverUrlLen = (int)strlen(serverUrl);
} else {
// Multicast discovery packet to try to find our server
if ((agent->multicastDiscovery != NULL) && (ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2)) == 65)) { ILibMulticastSocket_Broadcast(agent->multicastDiscovery, ILibScratchPad2, 64, 1); }
if ((agent->multicastDiscovery != NULL) && (ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2)) == 97)) { ILibMulticastSocket_Broadcast(agent->multicastDiscovery, ILibScratchPad2, 96, 1); }
ILibDestructParserResults(rs);
MeshServer_Connect(agent);
return;
@@ -2100,12 +2183,13 @@ void MeshAgent_Slave(MeshAgentHostContainer *agentHost)
void MeshAgent_ChainEnd(void *chain, void *user)
{
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
duk_destroy_heap(agent->meshCoreCtx);
if (agent->meshCoreCtx != NULL) { duk_destroy_heap(agent->meshCoreCtx); }
}
void MeshAgent_RunScriptOnly_Finalizer(duk_context *ctx, void *user)
{
MeshAgentHostContainer *agentHost = (MeshAgentHostContainer*)user;
agentHost->meshCoreCtx = NULL;
if (ILibIsChainBeingDestroyed(agentHost->chain) == 0)
{
MeshAgent_Stop(agentHost);
@@ -2557,6 +2641,8 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
int connectAgent = 0;
int pathLen = 0;
if (agentHost->meshCoreCtx_embeddedScript == NULL)
{
// Get the full path name of the JavaScript file
#ifdef WIN32
pathLen = GetFullPathName(argv[1], sizeof(ILibScratchPad2), ILibScratchPad2, NULL);
@@ -2629,6 +2715,20 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
scriptArgs[sx++] = argv[i];
}
}
}
else
{
// Embedded JavaScript
jsFile = agentHost->meshCoreCtx_embeddedScript;
jsFileLen = agentHost->meshCoreCtx_embeddedScriptLen;
scriptArgs = (char**)ILibMemory_Allocate((1 + argc) * sizeof(char*), 0, NULL, NULL);
for (i = 1; i < argc; ++i)
{
scriptArgs[i] = argv[i];
}
scriptArgs[i] = NULL;
scriptArgs[0] = agentHost->exePath;
}
// Start the JavaScript engine, run the loaded .js file
agentHost->localScript = 1;
@@ -2638,9 +2738,12 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
if (connectAgent != 0) { ILibDuktape_MeshAgent_Init(agentHost->meshCoreCtx, agentHost->chain, agentHost); }
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, jsFile, jsFileLen) != 0 || ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
{
if (strcmp(duk_safe_to_string(agentHost->meshCoreCtx, -1), "Process.exit() forced script termination") != 0)
{
// Error
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "Script Error: %s", duk_safe_to_string(agentHost->meshCoreCtx, -1));
}
duk_pop(agentHost->meshCoreCtx);
}
@@ -2701,13 +2804,15 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
exePath[x] = 0;
#endif
// Perform a self SHA256 Hash
util_sha256file(agentHost->exePath, agentHost->agentHash);
// Perform a self SHA384 Hash
util_sha384file(agentHost->exePath, agentHost->agentHash);
#ifdef _REMOTELOGGINGSERVER
{
int len;
if (agentHost->masterDb == NULL) { agentHost->masterDb = ILibSimpleDataStore_Create(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db")); }
if (agentHost->masterDb == NULL && ILibSimpleDataStore_Exists(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db")) != 0)
{
agentHost->masterDb = ILibSimpleDataStore_Create(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db"));
if (agentHost->masterDb != NULL)
{
if ((len = ILibSimpleDataStore_Get(agentHost->masterDb, "enableILibRemoteLogging", ILibScratchPad, sizeof(ILibScratchPad))) != 0)
@@ -2719,6 +2824,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
agentHost->masterDb = NULL;
}
}
}
#endif
ILibCriticalLogFilename = ILibString_Copy(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".log"), -1);
#ifndef MICROSTACK_NOTLS
@@ -2740,7 +2846,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
void *reserved[] = { agentHost, &paramLen, param };
// Check to see if we are running as just a JavaScript Engine
if (paramLen >= 2 && ILibString_EndsWith(param[1], -1, ".js", 3) != 0)
if (agentHost->meshCoreCtx_embeddedScript != NULL || (paramLen >= 2 && ILibString_EndsWith(param[1], -1, ".js", 3) != 0))
{
// We are acting as a scripting engine
ILibChain_RunOnMicrostackThreadEx(agentHost->chain, MeshAgent_ScriptMode_Dispatched, reserved);

View File

@@ -88,13 +88,13 @@ typedef enum AgentIdentifiers
// Commands with an id that starts with '{' (123, 0x7B) are reserved for JSON commands, that is commands 31488 (0x7B00) to 31743 (0x7BFF)
typedef enum MeshCommands_Binary
{
MeshCommand_AuthRequest = 1, // Server web certificate public key sha256 hash + agent or server nonce
MeshCommand_AuthRequest = 1, // Server web certificate public key sha384 hash + agent or server nonce
MeshCommand_AuthVerify = 2, // Agent or server signature
MeshCommand_AuthInfo = 3, // Agent information
MeshCommand_AuthConfirm = 4, // Server confirm to the agent that is it authenticated
MeshCommand_CoreModule = 10, // New core modules to be used instead of the old one, if empty, remove the core module
MeshCommand_CoreModuleHash = 11, // Request/return the SHA256 hash of the core module
MeshCommand_AgentHash = 12, // Request/return the SHA256 hash of the agent executable
MeshCommand_CoreModuleHash = 11, // Request/return the SHA384 hash of the core module
MeshCommand_AgentHash = 12, // Request/return the SHA384 hash of the agent executable
MeshCommand_AgentUpdate = 13, // Indicate the start and end of the mesh agent binary transfer
MeshCommand_AgentUpdateBlock = 14, // Part of the mesh agent sent from the server to the agent, confirmation/flowcontrol from agent to server
MeshCommand_AgentTag = 15 // Send the mesh agent tag to the server
@@ -149,6 +149,8 @@ typedef struct MeshAgentHostContainer
int slaveMode;
duk_context *meshCoreCtx;
char *meshCoreCtx_embeddedScript;
int meshCoreCtx_embeddedScriptLen;
MeshAgentDuktapePtrs *DuktapeMeshBindings;
ILibProcessPipe_Manager *pipeManager;

View File

@@ -17,7 +17,7 @@ limitations under the License.
#if !defined(__MeshDefines__)
#define __MeshDefined__
#define UTIL_HASHSIZE 32
#define UTIL_HASHSIZE 48
#define MESH_AGENT_PORT 16990 //!< Default Mesh Agent Port
#define MESH_AGENT_STUN_PORT 16991 //!< Default Mesh Agent STUN Port
#define MESH_AGENT_VERSION 1 //!< Used for self-update system.

View File

@@ -86,7 +86,7 @@ int signcheck_verifysign(char* filename, int upgrade)
{
if ((psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0)) != 0)
{
util_sha256((char*)(psProvCert->pCert->pbCertEncoded), psProvCert->pCert->cbCertEncoded, hash);
util_sha384((char*)(psProvCert->pCert->pbCertEncoded), psProvCert->pCert->cbCertEncoded, hash);
for (i = 0; (int)i < TrustedCertificatesCount; i++) if (memcmp(TrustedCertificates[i], hash, 32) == 0) found = 1;
}
}
@@ -132,7 +132,7 @@ int signcheck_verifysign(char* filename, int upgrade)
int endblock[4];
char* signatureblock = NULL;
int signatureblocklen = 0;
SHA256_CTX c;
SHA512_CTX c;
char *buf = NULL;
char *hashs = NULL;
int hashslen;
@@ -188,26 +188,26 @@ int signcheck_verifysign(char* filename, int upgrade)
if (agentid != g_agentid) { ILIBMESSAGE("BAD-ARCH-CHECK"); fclose(pFile); return 0; }
// Seek to the start and hash the entire file except for the signature stuff at the end
SHA256_Init(&c);
SHA384_Init(&c);
if (fseek(pFile, 0, SEEK_SET)) goto error;
i = totallen - (size_t)(endblock[0] + 16);
if ((buf = (char*)malloc(4096)) == NULL) goto error;
while ((i > 0) && (len = fread(buf, 1, i > 4096 ? 4096 : i, pFile)) > 0) { SHA256_Update(&c, buf, len); i -= len; }
while ((i > 0) && (len = fread(buf, 1, i > 4096 ? 4096 : i, pFile)) > 0) { SHA384_Update(&c, buf, len); i -= len; }
free(buf);
if (i != 0) goto error;
SHA256_Final((unsigned char*)totalfilehash, &c);
SHA384_Final((unsigned char*)totalfilehash, &c);
// Check that the file hash is the same as the second hash in the hash block
if (memcmp(hashs + 32, totalfilehash, 32) != 0) goto error;
if (memcmp(hashs + 48, totalfilehash, 48) != 0) goto error;
// Get the public certificate block
certbuflen = util_to_cer(cert, &certbuf);
// Compute the certificate key hash
util_sha256(certbuf, certbuflen, certhash);
util_sha384(certbuf, certbuflen, certhash);
// Check if the certificate is trusted
for (j = 0; j < TrustedCertificatesCount; j++) if (memcmp(TrustedCertificates[j], certhash, 32) == 0) found = 1;
for (j = 0; j < TrustedCertificatesCount; j++) if (memcmp(TrustedCertificates[j], certhash, 48) == 0) found = 1;
error:
// Clean up

View File

@@ -696,7 +696,7 @@ int main(int argc, char* argv[])
if (argc > 2 && memcmp(argv[1], "-faddr", 6) == 0)
{
uint64_t addrOffset;
util_hexToBuf(argv[2] + 2, strnlen_s(argv[2], 130) - 2, (char*)&addrOffset);
util_hexToBuf(argv[2] + 2, (int)strnlen_s(argv[2], 130) - 2, (char*)&addrOffset);
ILibChain_DebugOffset(ILibScratchPad, sizeof(ILibScratchPad), addrOffset);
printf("%s", ILibScratchPad);
return(0);

View File

@@ -42,6 +42,7 @@ typedef void(*ILibDuktape_DuplexStream_PauseResumeHandler)(ILibDuktape_DuplexStr
#define ILibDuktape_DuplexStream_Ready(duplexStream) ILibDuktape_WritableStream_Ready((duplexStream)->writableStream)
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) ILibDuktape_readableStream_WriteData((duplexStream)->readableStream, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx((duplexStream)->readableStream, streamReserved, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream)
#define ILibDuktape_DuplexStream_Closed(duplexStream) ILibDuktape_readableStream_Closed((duplexStream)->readableStream)

View File

@@ -19,6 +19,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx);
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter(duk_context *ctx, duk_idx_t i);
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx);
#define ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx) ILibDuktape_EventEmitter_GetEmitter(ctx, -1)
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr);
void ILibDuktape_EventEmitter_Init(duk_context *ctx);
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter); // Removes all event handlers/dispatchers

View File

@@ -397,6 +397,8 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
void *j = ILibDuktape_GetProcessObject(ctx);
ILibDuktape_EventEmitter *emitter;
if (strcmp(errmsg, "Process.exit() forced script termination") == 0) { return; }
duk_push_heapptr(ctx, j); // [process]
emitter = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
duk_pop(ctx); // ...

View File

@@ -40,7 +40,7 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
while (duk_next(ctx, -1, 1))
{
// [networkInterfaces][enum][adapter][array]
int count = duk_get_length(ctx, -1);
int count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [networkInterfaces][enum][adapter][array][obj]
@@ -48,7 +48,7 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
{
duk_get_prop_string(ctx, -1, "address");// [networkInterfaces][enum][adapter][array][obj][address]
buffer = (char*)duk_get_lstring(ctx, -1, &bufferLen);
ILibHashtable_Put(retVal, NULL, buffer, bufferLen, (void*)0x01);
ILibHashtable_Put(retVal, NULL, buffer, (int)bufferLen, (void*)0x01);
duk_pop(ctx); // [networkInterfaces][enum][adapter][array][obj]
}
duk_pop(ctx); // [networkInterfaces][enum][adapter][array]

View File

@@ -114,6 +114,18 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
}
return 1;
}
duk_ret_t ILibDuktape_Polyfills_Buffer_readInt32BE(duk_context *ctx)
{
int offset = duk_require_int(ctx, 0);
char *buffer;
duk_size_t bufferLen;
duk_push_this(ctx);
buffer = Duktape_GetBuffer(ctx, -1, &bufferLen);
duk_push_int(ctx, ntohl(((int*)(buffer + offset))[0]));
return(1);
}
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
{
// Polyfill 'Buffer.slice'
@@ -122,6 +134,8 @@ void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "readInt32BE");
duk_pop_3(ctx); // [g]
// Polyfill 'Buffer.toString()
@@ -159,7 +173,27 @@ duk_ret_t ILibDuktape_Polyfills_String_startsWith(duk_context *ctx)
return 1;
}
duk_ret_t ILibDuktape_Polyfills_String_endsWith(duk_context *ctx)
{
duk_size_t tokenLen;
char *token = Duktape_GetBuffer(ctx, 0, &tokenLen);
char *buffer;
duk_size_t bufferLen;
duk_push_this(ctx);
buffer = Duktape_GetBuffer(ctx, -1, &bufferLen);
if (ILibString_EndsWith(buffer, (int)bufferLen, token, (int)tokenLen) != 0)
{
duk_push_true(ctx);
}
else
{
duk_push_false(ctx);
}
return 1;
}
void ILibDuktape_Polyfills_String(duk_context *ctx)
{
// Polyfill 'String.startsWith'
@@ -167,6 +201,8 @@ void ILibDuktape_Polyfills_String(duk_context *ctx)
duk_get_prop_string(ctx, -1, "prototype"); // [string][proto]
duk_push_c_function(ctx, ILibDuktape_Polyfills_String_startsWith, DUK_VARARGS); // [string][proto][func]
duk_put_prop_string(ctx, -2, "startsWith"); // [string][proto]
duk_push_c_function(ctx, ILibDuktape_Polyfills_String_endsWith, DUK_VARARGS); // [string][proto][func]
duk_put_prop_string(ctx, -2, "endsWith"); // [string][proto]
duk_pop_2(ctx);
}
duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
@@ -189,6 +225,32 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
printf("\n");
return 0;
}
duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
{
#ifdef _REMOTELOGGING
void *chain = Duktape_GetChain(ctx);
int port = duk_require_int(ctx, 0);
duk_size_t pLen;
if (duk_peval_string(ctx, "process.argv0") != 0) { return(ILibDuktape_Error(ctx, "console.enableWebLog(): Couldn't fetch argv0")); }
char *p = (char*)duk_get_lstring(ctx, -1, &pLen);
if (ILibString_EndsWith(p, (int)pLen, ".js", 3) != 0)
{
memcpy_s(ILibScratchPad2, sizeof(ILibScratchPad2), p, pLen - 3);
sprintf_s(ILibScratchPad2 + (pLen - 3), sizeof(ILibScratchPad2) - 3, ".wlg");
}
else if (ILibString_EndsWith(p, (int)pLen, ".exe", 3) != 0)
{
memcpy_s(ILibScratchPad2, sizeof(ILibScratchPad2), p, pLen - 4);
sprintf_s(ILibScratchPad2 + (pLen - 3), sizeof(ILibScratchPad2) - 4, ".wlg");
}
else
{
sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s.wlg", p);
}
ILibStartDefaultLoggerEx(chain, (unsigned short)port, ILibScratchPad2);
#endif
return (0);
}
void ILibDuktape_Polyfills_Console(duk_context *ctx)
{
// Polyfill console.log()
@@ -204,6 +266,9 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
}
duk_push_c_function(ctx, ILibDuktape_Polyfills_Console_log, DUK_VARARGS); // [g][console][log]
duk_put_prop_string(ctx, -2, "log"); // [g][console]
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
duk_pop(ctx); // [g]
}
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
@@ -391,7 +456,7 @@ duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
char *module = (char*)Duktape_GetBuffer(ctx, 1, &moduleLen);
char *moduleName = (char*)duk_require_string(ctx, 0);
if (ILibDuktape_ModSearch_AddModule(ctx, moduleName, module, moduleLen) != 0)
if (ILibDuktape_ModSearch_AddModule(ctx, moduleName, module, (int)moduleLen) != 0)
{
return(ILibDuktape_Error(ctx, "Cannot add module: %s", moduleName));
}

View File

@@ -54,15 +54,17 @@ public:
\brief The ReadableStream.pipe() method attaches a WritableStream to the readable, causing it to switch automatically into flowing mode and push all of its data to the attached WritableStream.
*
* Flow control of data will be automatically managed so that the destination WritableStream is not overwhelmed by a faster ReadableStream.
\param destination[in] The WritableStream to attach to the ReadableStream.
\param destination \<WritableStream\> The WritableStream to attach to the ReadableStream.
\param options <Object> Optional parameters:\n
<b>dataTypeSkip</b> If set to 1, String values will only emit 'data' events instead of being piped to the WritableStream
*/
void pipe(WritableStream destination);
void pipe(destination[, options]);
/*!
\brief The ReadableStream.unpipe() method detaches a WritableStream previously attached using the ReadableStream.pipe() method.
*
\param destination[in] If specified, the WritableStream to detach. If not specified, all streams will be dettached.
\param destination \<WritableStream\> If specified, the WritableStream to detach. If not specified, all streams will be dettached.
*/
void unpipe(WritableStream destination);
void unpipe(destination);
/*!
@@ -98,12 +100,14 @@ typedef struct ILibDuktape_readableStream_bufferedData
{
struct ILibDuktape_readableStream_bufferedData *Next;
int bufferLen;
int Reserved;
char buffer[];
}ILibDuktape_readableStream_bufferedData;
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, char *buffer, int bufferLen)
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, int streamReserved, char *buffer, int bufferLen)
{
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)ILibMemory_Allocate(bufferLen + sizeof(ILibDuktape_readableStream_bufferedData), 0, NULL, NULL);
buffered->Reserved = streamReserved;
buffered->bufferLen = bufferLen;
memcpy_s(buffered->buffer, bufferLen, buffer, bufferLen);
@@ -134,8 +138,15 @@ void ILibDuktape_readableStream_WriteData_OnData_ChainThread(void *chain, void *
stream->paused = 0;
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
if (stream->extBuffer_Reserved == 0)
{
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, stream->extBuffer_buffer, stream->extBuffer_bufferLen);
}
else
{
duk_push_lstring(stream->ctx, stream->extBuffer_buffer, stream->extBuffer_bufferLen);
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
@@ -256,7 +267,7 @@ void ILibDuktape_readableStream_WriteData_ChainThread(void *chain, void *user)
}
}
int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, char* buffer, int bufferLen)
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen)
{
ILibDuktape_readableStream_nextWriteablePipe *w;
int nonNativeCount = 0;
@@ -264,10 +275,12 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
if (stream->paused != 0)
{
ILibDuktape_readableStream_WriteData_buffer(stream, buffer, bufferLen);
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
return(stream->paused);
}
if (stream->bypassValue == 0 || stream->bypassValue != streamReserved)
{
sem_wait(&(stream->pipeLock));
w = stream->nextWriteable;
while (w != NULL)
@@ -282,6 +295,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
if (nonNativeCount > 0)
{
// There are piped Pure JavaScript objects... We must context switch to Microstack Thread
stream->extBuffer_Reserved = streamReserved;
stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen;
sem_post(&(stream->pipeLock));
@@ -298,6 +312,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
if (w->nativeWritable != NULL)
{
ILibDuktape_WritableStream *ws = (ILibDuktape_WritableStream*)w->nativeWritable;
ws->Reserved = streamReserved;
switch (ws->WriteSink(ws, buffer, bufferLen, ws->WriteSink_User))
{
case ILibTransport_DoneState_INCOMPLETE:
@@ -345,7 +360,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
{
sem_post(&(stream->pipeLock));
}
}
if (stream->OnData != NULL)
{
@@ -353,8 +368,15 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
{
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
if (streamReserved == 0)
{
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, buffer, bufferLen);
}
else
{
duk_push_lstring(stream->ctx, buffer, bufferLen); // [func][this][string]
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
@@ -365,6 +387,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
{
// Need to PAUSE, and context switch to Chain Thread, so we can dispatch into JavaScript
if (stream->paused == 0 && stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
stream->extBuffer_Reserved = streamReserved;
stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen;
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, stream);
@@ -375,7 +398,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
// If we get here, it means we are writing data, but nobody is going to be receiving it...
// So we need to buffer the data, so when we are resumed later, we can retry
ILibDuktape_readableStream_WriteData_buffer(stream, buffer, bufferLen);
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
}
else if (stream->OnEnd != NULL)
{
@@ -477,8 +500,7 @@ int ILibDuktape_readableStream_resume_flush(ILibDuktape_readableStream *rs)
while ((buffered = rs->paused_data))
{
rs->paused_data = buffered->Next;
if (ILibDuktape_readableStream_WriteData(rs, buffered->buffer, buffered->bufferLen) != 0)
if (ILibDuktape_readableStream_WriteDataEx(rs, buffered->Reserved, buffered->buffer, buffered->bufferLen) != 0)
{
// Send did not complete, so lets exit out, and we'll continue next time.
free(buffered);
@@ -515,12 +537,18 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
{
ILibDuktape_readableStream *rstream;
ILibDuktape_readableStream_nextWriteablePipe *w;
int nargs = duk_get_top(ctx);
duk_push_this(ctx); // [readable]
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS); // [readable][ptrs]
rstream = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [readable]
if (nargs > 1 && duk_is_object(ctx, 1))
{
rstream->bypassValue = Duktape_GetIntPropertyValue(ctx, 1, "dataTypeSkip", 0);
}
duk_push_object(ctx); // [readable][nextWriteable]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_readableStream_nextWriteablePipe)); // [readable][nextWriteable][ptrBuffer]
w = (ILibDuktape_readableStream_nextWriteablePipe*)Duktape_GetBuffer(ctx, -1, NULL);

View File

@@ -42,7 +42,7 @@ typedef struct ILibDuktape_readableStream
void *OnEnd;
void *extBuffer;
char *extBuffer_buffer;
int extBuffer_bufferLen;
int extBuffer_bufferLen, extBuffer_Reserved;
void *user;
ILibDuktape_readableStream_nextWriteablePipe *nextWriteable;
@@ -54,7 +54,7 @@ typedef struct ILibDuktape_readableStream
#else
int pipe_pendingCount; // No Atomic Built-ins... Use a Mutex
#endif
int bypassValue;
int paused;
void *paused_data;
ILibDuktape_readableStream_PauseResumeHandler PauseHandler;
@@ -65,8 +65,10 @@ typedef struct ILibDuktape_readableStream
ILibDuktape_readableStream* ILibDuktape_InitReadableStream(duk_context *ctx, ILibDuktape_readableStream_PauseResumeHandler OnPause, ILibDuktape_readableStream_PauseResumeHandler OnResume, void *user);
#define ILibDuktape_ReadableStream_Init(ctx, OnPause, OnResume, user) ILibDuktape_InitReadableStream(ctx, OnPause, OnResume, user)
#define ILibDuktape_readableStream_SetPauseResumeHandlers(stream, PauseFunc, ResumeFunc, userObj) ((ILibDuktape_readableStream*)stream)->PauseHandler = PauseFunc; ((ILibDuktape_readableStream*)stream)->ResumeHandler = ResumeFunc; ((ILibDuktape_readableStream*)stream)->user = userObj;
int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, char* buffer, int bufferLen);
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen);
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
#define ILibDuktape_readableStream_WriteData(stream, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx(stream, 0, buffer, bufferLen)
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream);
#endif

View File

@@ -8,6 +8,7 @@
#define ILibDuktape_MD5_PTR "\xFF_MD5PTR"
#define ILibDuktape_SHA256_PTR "\xFF_SHA256PTR"
#define ILibDuktape_SHA512_PTR "\xFF_SHA512PTR"
#define ILibDuktape_SHA256_SIGNER_PTR "\xFF_SHA256_SIGNER_PTR"
#define ILibDuktape_SHA256_SIGNER_CERT "\xFF_SHA256_SIGNER_CERT"
#define ILibDuktape_SHA256_SIGNER_CERT_ALLOC "\xFF_SHA256_SIGNER_CERT_ALLOC"
@@ -25,6 +26,16 @@ typedef struct ILibDuktape_SHA256_Data
char buffer[33];
SHA256_CTX shctx;
}ILibDuktape_SHA256_Data;
typedef struct ILibDuktape_SHA512_Data
{
duk_context *ctx;
void *object;
void *OnHash;
void *OnHashString;
char buffer[65];
SHA512_CTX shctx;
}ILibDuktape_SHA512_Data;
typedef struct ILibDuktape_MD5_Data
{
duk_context *ctx;
@@ -51,6 +62,10 @@ duk_ret_t ILibDuktape_SHA256_Finalizer(duk_context *ctx)
{
return 0;
}
duk_ret_t ILibDuktape_SHA384_Finalizer(duk_context *ctx)
{
return 0;
}
ILibTransport_DoneState ILibDuktape_SHA256_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
@@ -58,6 +73,13 @@ ILibTransport_DoneState ILibDuktape_SHA256_Write(struct ILibDuktape_WritableStre
SHA256_Update(&(data->shctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
SHA384_Update(&(data->shctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
{
@@ -89,6 +111,36 @@ void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *use
duk_pop(data->ctx); // ...
}
}
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
data->buffer[48] = 0;
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
if (data->ctx != NULL && data->OnHash != NULL)
{
duk_push_heapptr(data->ctx, data->OnHash); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_external_buffer(data->ctx); // [func][this][hash]
duk_config_buffer(data->ctx, -1, data->buffer, 48);
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
if (data->ctx != NULL && data->OnHashString != NULL)
{
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [func][this][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
}
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
{
ILibDuktape_SHA256_Signer_Data *data;
@@ -268,7 +320,35 @@ duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
}
return(1);
}
duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
duk_size_t bufferLen;
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_this(ctx); // [sha]
duk_get_prop_string(ctx, -1, ILibDuktape_SHA512_PTR);
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
SHA384_Init(&(data->shctx));
SHA384_Update(&(data->shctx), buffer, bufferLen);
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
data->buffer[48] = 0;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "strRet");
if (duk_get_boolean(ctx, -1) == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, 48);
}
else
{
util_tohex(data->buffer, 48, ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
}
return(1);
}
ILibTransport_DoneState ILibDuktape_MD5_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
@@ -388,11 +468,43 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
return(1);
}
duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [sha]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
SHA384_Init(&(data->shctx));
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA384_Write, ILibDuktape_SHA384_End, data);
return(1);
}
void ILibDuktape_SHA256_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA256_Create, 0);
}
void ILibDuktape_SHA384_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA384_Create, 0);
}
void ILibDuktape_MD5_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [md5]
@@ -404,6 +516,7 @@ void ILibDuktape_SHA256_Init(duk_context * ctx)
#ifndef MICROSTACK_NOTLS
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Signer", ILibDuktape_SHA256_SIGNER_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Verifier", ILibDuktape_SHA256_VERIFY_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA384Stream", ILibDuktape_SHA384_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream", ILibDuktape_SHA256_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "MD5Stream", ILibDuktape_MD5_PUSH);
#endif

View File

@@ -211,8 +211,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Exit(duk_context *ctx)
tmp = (void**)ILibMemory_Allocate(sizeof(void*), 0, NULL, NULL);
tmp[0] = ctx;
ILibLifeTime_Add(ILibGetBaseTimer(Duktape_GetChain(ctx)), tmp, 0, ILibDuktape_ScriptContainer_Process_ExitCallback, NULL);
return 0;
return(ILibDuktape_Error(ctx, "Process.exit() forced script termination"));
}
@@ -339,7 +338,7 @@ SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx
duk_get_prop_string(ctx, -1, "process"); // [g][process]
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_ArgArray); // [g][process][array]
int i, count = duk_get_length(ctx, -1);
int i, count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [g][process][array][index]
@@ -369,7 +368,7 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_EN
void *ILibDuktape_ScriptContainer_Engine_malloc(void *udata, duk_size_t size)
{
return(ILibMemory_Allocate(size, 0, NULL, NULL));
return(ILibMemory_Allocate((int)size, 0, NULL, NULL));
}
void *ILibDuktape_ScriptContainer_Engine_realloc(void *udata, void *ptr, duk_size_t size)
{
@@ -837,7 +836,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
char *moduleName = Duktape_GetStringPropertyValue(slave->ctx, -1, "name", NULL);
char *module = Duktape_GetStringPropertyValueEx(slave->ctx, -1, "module", NULL, &moduleLen);
ILibDuktape_ModSearch_AddModule(slave->ctx, moduleName, module, moduleLen);
ILibDuktape_ModSearch_AddModule(slave->ctx, moduleName, module, (int)moduleLen);
ILibRemoteLogging_printf(ILibChainGetLogger(slave->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "MeshAgent_Slave: Added module %s", moduleName);
break;
@@ -850,7 +849,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
if (duk_has_prop_string(codec, -1, "argv"))
{
duk_get_prop_string(codec, -1, "argv"); // [json][argv]
int i, argLen = duk_get_length(codec, -1);
int i, argLen = (int)duk_get_length(codec, -1);
if (argLen > 0)
{
if ((argLen + 1) * sizeof(void*) > sizeof(ILibScratchPad))
@@ -922,7 +921,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
{
// Execute String
execData = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "string", NULL, &execDataLen);
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, execData, execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, execData, (int)execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
{
// Success
duk_push_object(slave->ctx); // [json][retJSON]
@@ -964,7 +963,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
{
// Execute Path
execData = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "path", NULL, &execDataLen);
if (ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(slave->ctx, execData, execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx))
if (ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(slave->ctx, execData, (int)execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx))
{
// SUCCESS
duk_push_object(slave->ctx); // [json][retJSON]
@@ -1224,10 +1223,10 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
duk_json_encode(ctx, -1);
buffer = (char*)duk_get_lstring(ctx, -1, &bufferLen);
((int*)header)[0] = bufferLen + 4;
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_WriteStdIn(master->child, header, 4, ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, bufferLen, ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
return(0);
}
@@ -1490,7 +1489,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
duk_swap_top(ctx, -2); // [json][container]
((int*)header)[0] = bufferLen + 4;
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);

View File

@@ -157,6 +157,8 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
int cbIndex = 0;
stream->Reserved = duk_is_string(ctx, 0) ? 1 : 0;
for (cbIndex = 1; cbIndex < nargs; ++cbIndex)
{
if (duk_is_function(ctx, cbIndex)) { break; }

View File

@@ -44,6 +44,7 @@ typedef struct ILibDuktape_WritableStream
ILibDuktape_WritableStream_EndHandler EndSink;
ILibDuktape_WritableStream_PipeHandler PipeSink;
void *WriteSink_User;
int Reserved;
} ILibDuktape_WritableStream;
#define ILibDuktape_WritableStream_WSPTRS "\xFF_WritableStream_PTRS"

View File

@@ -125,11 +125,11 @@ char* ILibDuktape_fs_fixLinuxPath(char *path)
int len = end;
if (end > (sizeof(ILibDuktape_fs_linuxPath)-1)) { return(NULL); }
if (path[0] == '/') { start = 1; } else { ++len; }
//if (path[0] == '/') { start = 1; } else { ++len; }
if (path[end - 1] == '*') { --end; --len; }
ILibDuktape_fs_linuxPath[0] = '/';
memcpy_s(ILibDuktape_fs_linuxPath + 1, sizeof(ILibDuktape_fs_linuxPath) - 1, path + start, end);
memcpy_s(ILibDuktape_fs_linuxPath, sizeof(ILibDuktape_fs_linuxPath), path + start, end);
ILibDuktape_fs_linuxPath[len] = 0; // Klocwork is being retarded, as it is too stupid to notice the size check at the top of this func
return(ILibDuktape_fs_linuxPath);
}
@@ -1319,7 +1319,7 @@ public:
Array<String> readdirSync(path[, options]);
/*!
\brief Returns a new WritableStream
\param path \<String]>
\param path \<String\>
\param options <Object> has the following defaults:\n
<b>flags</b> \<String\> 'w'\n
<b>encoding</b> \<String\> 'utf8'\n

View File

@@ -36,6 +36,7 @@ limitations under the License.
#include "ILibDuktape_EventEmitter.h"
#include "microstack/ILibCrypto.h"
#define HTTP_SERVER_PTR "\xFF_ServerPtr"
#define HTTP_WEBCLIENT_MGR "_RequestManagerPtr"
#define NativeSessionPtr "\xFF_SessionPtr"
#define SessionPtrJS "\xFF_SessionPtr_JS"
@@ -43,6 +44,7 @@ limitations under the License.
#define TLS_CERT "\xFF_cert"
#define TLS_CERT_NON_LEAF "\xFF_cert_nonleaf"
#define HTTP_DEFAULT_PROTO_KEY "\xFF_defaultProto"
#define HTTP_REQUEST_USER_PTR "\xFF_request_user_ptr"
#define HTTP_REQUEST_TOKEN_PTR "_TokenPtr"
#define HTTP_SOCKET_PTRS "\xFF_socket_ptrs"
#define HTTP_SOCKET_BUFFERPTR "\xFF_socket_bufferptr"
@@ -56,6 +58,7 @@ limitations under the License.
#define HTTP_DIGEST "\xFF_HTTP_DIGEST"
#define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST"
#define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR"
#define CLIENTREQUEST_EVENT_NAME "\xFF_CLIENTREQUEST_EVENT_NAME"
extern duk_idx_t ILibWebServer_DukTape_Push_ILibWebServerSession(duk_context *ctx, ILibWebServer_Session *session);
void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket);
@@ -80,18 +83,20 @@ typedef struct ILibDuktape_http_requestClient_callbacks
void *readableStream;
void *requestStream;
void *OnReceive;
void *OnContinue;
#ifndef MICROSTACK_NOTLS
int rejectUnauthorized;
void *checkServerIdentity;
#endif
}ILibDuktape_http_requestClient_callbacks;
typedef struct ILibDuktape_http_server_session_ptrs
typedef struct ILibDuktape_http_server_ptrs
{
void *ctx;
void *serverObject;
void *OnResponse;
void *OnUpgrade;
void *OnCheckContinue;
void *OnConnect;
}ILibDuktape_http_server_ptrs;
typedef struct ILibDuktape_http_session_ptrs
@@ -99,6 +104,12 @@ typedef struct ILibDuktape_http_session_ptrs
ILibDuktape_readableStream *req;
ILibDuktape_WritableStream *res;
}ILibDuktape_http_session_ptrs;
typedef struct ILibDuktape_http_server_websocket_ptrs
{
ILibDuktape_EventEmitter *emitter;
ILibDuktape_DuplexStream *ds;
ILibWebServer_Session *session;
}ILibDuktape_http_server_websocket_ptrs;
typedef struct ILibDuktape_WebSocket_Pointers
{
@@ -208,7 +219,7 @@ duk_ret_t ILibDuktape_http_serverresponse_end(duk_context *ctx)
int nargs = duk_get_top(ctx);
duk_push_this(ctx); // [res]
duk_get_prop_string(ctx, -1, "SessionPtr"); // [res][session]
duk_get_prop_string(ctx, -1, NativeSessionPtr); // [res][session]
session = (ILibWebServer_Session*)duk_to_pointer(ctx, -1); // [res][session]
duk_pop(ctx); // [res]
duk_get_prop_string(ctx, -1, "PacketPtr"); // [res][packet]
@@ -274,7 +285,7 @@ duk_ret_t ILibDuktape_http_serverresponse_writeHead(duk_context *ctx)
duk_get_prop_string(ctx, -1, "PacketPtr"); // [response][packet]
packet = (ILibHTTPPacket*)duk_to_pointer(ctx, -1);
duk_del_prop_string(ctx, -2, "PacketPtr");
duk_get_prop_string(ctx, -2, "SessionPtr"); // [response][packet][session]
duk_get_prop_string(ctx, -2, NativeSessionPtr); // [response][packet][session]
session = (ILibWebServer_Session*)duk_to_pointer(ctx, -1);
if (nargs < 1) { duk_push_string(ctx, "Missing Status Code"); duk_throw(ctx); return(DUK_RET_ERROR); }
@@ -344,6 +355,15 @@ duk_ret_t ILibDuktape_http_server_ServerResponse_Finalizer(duk_context *ctx)
}
return 0;
}
duk_ret_t ILibDuktape_http_server_ServerResponse_writeContinue(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_Session *session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
ILibWebServer_Send_Raw(session, "HTTP/1.1 100 Continue\r\n\r\n", 25, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_NotDone);
return(0);
}
ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_context *ctx, ILibWebServer_Session *session)
{
ILibHTTPPacket *packet = ILibCreateEmptyPacket();
@@ -351,7 +371,7 @@ ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_cont
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, session); // [obj][session]
duk_put_prop_string(ctx, -2, "SessionPtr"); // [obj]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [obj]
duk_push_pointer(ctx, packet); // [obj][packet]
duk_put_prop_string(ctx, -2, "PacketPtr"); // [obj]
duk_push_int(ctx, 500); // [obj][statusCode]
@@ -368,6 +388,8 @@ ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_cont
duk_push_c_function(ctx, ILibDuktape_http_serverresponse_writeHead, DUK_VARARGS); // [obj][func]
duk_put_prop_string(ctx, -2, "writeHead"); // [obj]
ILibDuktape_CreateInstanceMethod(ctx, "writeContinue", ILibDuktape_http_server_ServerResponse_writeContinue, 0);
return ILibDuktape_WritableStream_Init(ctx, ILibDuktape_http_server_WriteResponse, ILibDuktape_http_server_EndResponse, session);
}
@@ -456,8 +478,8 @@ void ILibDuktape_http_server_NativeSession_PUSH(duk_context *ctx, ILibWebServer_
ILibDuktape_CreateInstanceMethod(ctx, "Digest_SendUnauthorized", ILibDuktape_http_server_NativeSession_Digest_SendUnAuthorized, 2);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_GetUsername", ILibDuktape_http_server_NativeSession_Digest_GetUsername, 0);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_ValidatePassword", ILibDuktape_http_server_NativeSession_Digest_ValidatePassword, 1);
ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_GetDataType", ILibDuktape_http_server_NativeSession_WebSocket_GetDataType, 0);
ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_Upgrade", ILibDuktape_http_server_NativeSession_WebSocket_Upgrade, DUK_VARARGS);
//ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_GetDataType", ILibDuktape_http_server_NativeSession_WebSocket_GetDataType, 0);
//ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_Upgrade", ILibDuktape_http_server_NativeSession_WebSocket_Upgrade, DUK_VARARGS);
}
@@ -564,7 +586,10 @@ void ILibDuktape_http_server_PUSH_IncomingMessage(duk_context *ctx, ILibHTTPPack
{
duk_push_pointer(ctx, session); // [obj][session]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [obj]
ILibDuktape_CreateEventWithGetter(ctx, "NativeSession", ILibDuktape_http_server_NativeSession_Getter);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_IsAuthenticated", ILibDuktape_http_server_NativeSession_Digest_IsAuthenticated, 1);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_SendUnauthorized", ILibDuktape_http_server_NativeSession_Digest_SendUnAuthorized, 2);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_GetUsername", ILibDuktape_http_server_NativeSession_Digest_GetUsername, 0);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_ValidatePassword", ILibDuktape_http_server_NativeSession_Digest_ValidatePassword, 1);
}
if (packet != NULL && packet->Directive != NULL)
{
@@ -612,13 +637,118 @@ void ILibDuktape_http_server_Resume(ILibDuktape_readableStream *sender, void *us
{
ILibWebServer_Resume((ILibWebServer_Session*)user);
}
ILibTransport_DoneState ILibDuktape_http_server_webSocket_WriteHandler(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
return((ILibTransport_DoneState)ILibWebServer_WebSocket_Send(((ILibDuktape_http_server_websocket_ptrs*)user)->session, buffer, bufferLen, stream->writableStream->Reserved == 0 ? ILibWebServer_WebSocket_DataType_BINARY : ILibWebServer_WebSocket_DataType_TEXT, ILibAsyncSocket_MemoryOwnership_USER, ILibWebServer_WebSocket_FragmentFlag_Complete));
}
void ILibDuktape_http_server_webSocket_EndHandler(ILibDuktape_DuplexStream *stream, void *user)
{
ILibWebServer_WebSocket_Close(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_PauseHandler(ILibDuktape_DuplexStream *sender, void *user)
{
ILibWebServer_Pause(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_ResumeHandler(ILibDuktape_DuplexStream *sender, void *user)
{
ILibWebServer_Resume(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_OnReceive(struct ILibWebServer_Session *sender, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebServer_DoneFlag done)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
*beginPointer = endPointer;
if (done == ILibWebServer_DoneFlag_Done)
{
ILibDuktape_DuplexStream_WriteEnd(ptrs->ds);
sender->OnDisconnect = NULL;
}
else
{
ILibDuktape_DuplexStream_WriteDataEx(ptrs->ds, ILibWebServer_WebSocket_GetDataType(sender) == ILibWebServer_WebSocket_DataType_TEXT ? 1 : 0, bodyBuffer, endPointer);
}
}
void ILibDuktape_http_server_webSocket_OnDisconnect(struct ILibWebServer_Session *sender)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
ILibDuktape_DuplexStream_WriteEnd(ptrs->ds);
sender->OnDisconnect = NULL;
duk_push_heapptr(ptrs->emitter->ctx, ptrs->emitter->object);
duk_del_prop_string(ptrs->emitter->ctx, -1, NativeSessionPtr);
duk_pop(ptrs->emitter->ctx);
}
void ILibDuktape_http_server_webSocket_OnSendOK(struct ILibWebServer_Session *sender)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
ILibDuktape_DuplexStream_Ready(ptrs->ds);
}
void ILibDuktape_http_server_IntermediateSocket_Finalizer(duk_context *ctx, void *obj)
{
duk_push_heapptr(ctx, obj);
if (duk_has_prop_string(ctx, -1, NativeSessionPtr))
{
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_Session *session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
session->OnDisconnect = NULL;
session->OnReceive = NULL;
session->OnSendOK = NULL;
ILibWebServer_DisconnectSession(session);
}
}
duk_ret_t ILibDuktape_http_server_IntermediateSocket_upgradeWebSocket(duk_context *ctx)
{
ILibWebServer_Session *session;
int bufferSize = duk_get_top(ctx) == 0 ? 65535 : duk_require_int(ctx, 0);
duk_push_this(ctx); // [socket]
duk_get_prop_string(ctx, -1, NativeSessionPtr); // [socket][ptr]
session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
duk_pop(ctx); // [socket]
if (ILibWebServer_UpgradeWebSocket(session, bufferSize) != 0) { return(ILibDuktape_Error(ctx, "upgradeWebSocket(): Invalid State")); }
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_http_server_websocket_ptrs)); // [socket][buffer]
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)Duktape_GetBuffer(ctx, -1, NULL);
memset(ptrs, 0, sizeof(ILibDuktape_http_server_websocket_ptrs));
duk_put_prop_string(ctx, -2, HTTP_SOCKET_PTRS); // [socket]
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_http_server_IntermediateSocket_Finalizer);
((void**)session->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0] = ptrs;
ptrs->session = session;
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
ptrs->ds = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_http_server_webSocket_WriteHandler, ILibDuktape_http_server_webSocket_EndHandler, ILibDuktape_http_server_webSocket_PauseHandler, ILibDuktape_http_server_webSocket_ResumeHandler, ptrs);
// Redirect these events, because it's now a websocket
session->OnDisconnect = ILibDuktape_http_server_webSocket_OnDisconnect;
session->OnReceive = ILibDuktape_http_server_webSocket_OnReceive;
session->OnSendOK = ILibDuktape_http_server_webSocket_OnSendOK;
return(1);
}
duk_ret_t ILibDuktape_http_server_IntermediateSocket_end(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_DisconnectSession((ILibWebServer_Session*)duk_get_pointer(ctx, -1));
return(0);
}
void ILibDuktape_http_server_PUSH_IntermediateSocket(duk_context *ctx, ILibWebServer_Session *session)
{
duk_push_object(ctx); // [sock]
duk_push_pointer(ctx, session); // [sock][session]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [sock]
ILibDuktape_CreateInstanceMethod(ctx, "upgradeWebSocket", ILibDuktape_http_server_IntermediateSocket_upgradeWebSocket, DUK_VARARGS);
ILibDuktape_CreateProperty_InstanceMethod(ctx, "end", ILibDuktape_http_server_IntermediateSocket_end, 0);
}
void ILibDuktape_http_server_OnReceive(struct ILibWebServer_Session *sender, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebServer_DoneFlag done)
{
ILibDuktape_http_server_ptrs* serverPtrs = (ILibDuktape_http_server_ptrs*)sender->ParentExtraMemory;
ILibDuktape_http_session_ptrs *sessionPtrs = (ILibDuktape_http_session_ptrs*)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr;
char *headerVal;
int headerValLen;
int r = 0;
if (ILibGetHeaderLineEx(header, "upgrade", 7, NULL) != NULL)
@@ -630,13 +760,39 @@ void ILibDuktape_http_server_OnReceive(struct ILibWebServer_Session *sender, int
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][this][incoming]
ILibDuktape_http_server_PUSH_IntermediateSocket(serverPtrs->ctx, sender); // [func][this][incoming][socket]
duk_push_null(serverPtrs->ctx); // [func][this][incoming][socket][head]
if (duk_pcall_method(serverPtrs->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(serverPtrs->ctx, "Server.OnUpgrade(): "); }
duk_pop(serverPtrs->ctx); // ...
//ILibDuktape_EventEmitter_RemoveAllListeners();
}
}
return;
}
if ((headerVal = ILibGetHeaderLineEx(header, "expect", 6, &headerValLen)) != NULL)
{
if (ILibString_StartsWith(headerVal, headerValLen, "100-", 4))
{
if (serverPtrs->OnCheckContinue != NULL)
{
duk_push_heapptr(serverPtrs->ctx, serverPtrs->OnCheckContinue); // [func]
duk_push_heapptr(serverPtrs->ctx, serverPtrs->serverObject); // [func][this]
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][this][incoming]
sessionPtrs->req = ILibDuktape_InitReadableStream(serverPtrs->ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(sessionPtrs->req, ILibDuktape_http_server_Pause, ILibDuktape_http_server_Resume, sender);
sessionPtrs->res = ILibDuktape_http_server_PUSH_ServerResponse(serverPtrs->ctx, sender);// [func][this][incoming][res]
if (duk_pcall_method(serverPtrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(serverPtrs->ctx, "httpServer.onCheckContinue(): "); }
duk_pop(serverPtrs->ctx); // ...
}
else
{
// Noboddy is listening for checkContinue, so we must send a 100-Continue manually
ILibWebServer_Send_Raw(sender, "HTTP/1.1 Continue\r\n\r\n", 25, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_NotDone);
}
ILibDeleteHeaderLine(header, "expect", 6);
}
}
else
{
// The very first time, Server.request event will be emitted
if (sessionPtrs->req == NULL && serverPtrs->OnResponse != NULL)
{
@@ -657,7 +813,7 @@ void ILibDuktape_http_server_OnReceive(struct ILibWebServer_Session *sender, int
}
duk_pop(serverPtrs->ctx); // ...
}
}
// Now we just write to the ReadableStream
if (sessionPtrs->req != NULL)
{
@@ -727,6 +883,20 @@ int ILibDuktape_http_server_clientVerify(ILibWebServer_ServerToken sender, int p
return retVal;
}
#endif
duk_ret_t ILibDuktape_http_server_finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, HTTP_SERVER_PTR);
ILibWebServer_ServerToken server = (ILibWebServer_ServerToken)duk_get_pointer(ctx, -1);
void *chain = Duktape_GetChain(ctx);
if (ILibIsChainBeingDestroyed(chain) == 0)
{
// SafeRemove Server here...
ILibChain_SafeRemove(chain, server);
}
return(0);
}
duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
@@ -735,7 +905,6 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
int maxConnections = nargs > 2 ? duk_require_int(ctx, 2) : 5;
void *chain;
ILibWebServer_ServerToken server;
char *key;
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
duk_push_this(ctx); // [server]
@@ -750,6 +919,7 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "request", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnResponse));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "connect", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnConnect));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "upgrade", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnUpgrade));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "checkContinue", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnCheckContinue));
#ifndef MICROSTACK_NOTLS
if (duk_has_prop_string(ctx, -1, TLSPTR))
@@ -774,13 +944,8 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
#endif
duk_push_pointer(ctx, server); // [server][serverPtr]
duk_put_prop_string(ctx, -2, "ServerPtr"); // [server]
key = Duktape_GetStashKey(server);
duk_push_heap_stash(ctx); // [server][stash]
duk_swap_top(ctx, -2); // [stash][server]
duk_put_prop_string(ctx, -2, key); // [stash]
duk_put_prop_string(ctx, -2, HTTP_SERVER_PTR); // [server]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_http_server_finalizer);
return 0;
}
@@ -808,6 +973,7 @@ duk_ret_t ILibDuktape_http_createServer(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "listening");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "checkContinue");
for (i = 0; i < nargs; ++i)
{
@@ -943,6 +1109,8 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
return;
}
if ((header->StatusCode == 100 && ptrs->OnContinue != NULL) || ptrs->OnReceive != NULL)
{
ILibDuktape_http_server_PUSH_IncomingMessage(ctx, header, NULL); // [iMsg]
duk_push_pointer(ctx, WebStateObject);
duk_put_prop_string(ctx, -2, HTTP_INCOMINGMSG_WebStateObject);
@@ -955,14 +1123,21 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
duk_dup(ctx, -1); // [clientRequest][iMsg][iMsg]
duk_put_prop_string(ctx, -3, "_iMsgPtr"); // [clientRequest][iMsg]
duk_swap_top(ctx, -2); // [iMsg][clientRequest]
if (header->StatusCode == 100 && ptrs->OnContinue != NULL)
{
duk_push_heapptr(ctx, ptrs->OnContinue); // [iMsg][clientRequest][func]
}
else
{
duk_push_heapptr(ctx, ptrs->OnReceive); // [iMsg][clientRequest][func]
}
duk_swap(ctx, -3, -1); // [func][clientRequest/this][iMsg]
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx); // ...
}
if (endPointer > 0) { r += ILibDuktape_readableStream_WriteData(ptrs->readableStream, bodyBuffer + *beginPointer, endPointer - *beginPointer); }
if (r == 0 && recvStatus == ILibWebClient_ReceiveStatus_Complete) { r += ILibDuktape_readableStream_WriteEnd(ptrs->readableStream); }
}
@@ -1137,6 +1312,10 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
ILibDuktape_WebSocket_Pointers *ptrs = (ILibDuktape_WebSocket_Pointers*)user2;
if (ctx == NULL || ptrs == NULL) { return; }
duk_push_heapptr(ctx, ptrs->clientRequest_ptr);
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR);
void **user = ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_GetRequestToken_FromStateObject(WebStateObject));
duk_pop(ctx);
if (header != NULL && header->StatusCode != 101)
{
@@ -1152,6 +1331,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
duk_pop(ctx); // ...
*beginPointer = endPointer;
user[1] = NULL;
return;
}
@@ -1208,6 +1388,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
duk_pop(ctx); //[clientRequest]
}
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR);
duk_del_prop_string(ctx, -1, HTTP_REQUEST_USER_PTR);
duk_pop(ctx);
if (ptrs->socket_ptr != NULL)
@@ -1223,6 +1404,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter_GetEmitter(ctx, -1));
duk_pop(ctx);
}
user[1] = NULL;
}
}
void ILibDuktape_http_request_OnSendOK(ILibWebClient_StateObject sender, void *user1, void *user2)
@@ -1313,7 +1495,6 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
char *path, *method;
duk_size_t pathLen, methodLen;
char *proto = Duktape_GetStringPropertyValue(ctx, 0, "protocol", ILibDuktape_http_getDefaultProto(ctx));
#ifndef MICROSTACK_NOTLS
ILibWebClient_RequestToken_HTTPS protocol = (strncmp(proto, "https:", 6) == 0 || strncmp(proto, "wss:", 4) == 0) ? ILibWebClient_RequestToken_USE_HTTPS : ILibWebClient_RequestToken_USE_HTTP;
@@ -1531,6 +1712,14 @@ duk_ret_t ILibDuktape_http_request_finalizer(duk_context *ctx)
ILibWebClient_RequestToken token;
void **user;
if (duk_has_prop_string(ctx, 0, HTTP_REQUEST_USER_PTR))
{
duk_get_prop_string(ctx, 0, HTTP_REQUEST_USER_PTR);
user = (void**)duk_get_pointer(ctx, -1);
user[1] = NULL;
}
if (duk_has_prop_string(ctx, 0, HTTP_CLIENTREQUEST_DATAPTR))
{
duk_get_prop_string(ctx, 0, HTTP_CLIENTREQUEST_DATAPTR);
@@ -1554,6 +1743,7 @@ duk_ret_t ILibDuktape_http_request_finalizer(duk_context *ctx)
ILibWebClient_CancelRequest(token);
}
}
return 0;
}
duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
@@ -1563,7 +1753,7 @@ duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket)
{
ILibDuktape_EventEmitter *emitter = NULL;
void **user = ILibWebClient_RequestToken_GetUserObjects(token);
void **user = ILibWebClient_RequestToken_GetUserObjects_Tail(token);
if (user[1] != NULL && ((ILibDuktape_http_request_dataType*)user[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request &&
((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest != NULL)
@@ -1573,6 +1763,9 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
}
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, user);
duk_put_prop_string(ctx, -2, HTTP_REQUEST_USER_PTR);
duk_push_pointer(ctx, token); // [obj][token]
duk_put_prop_string(ctx, -2, HTTP_REQUEST_TOKEN_PTR); // [obj]
duk_push_fixed_buffer(ctx, isWebSocket == 0 ? sizeof(ILibDuktape_http_requestClient_callbacks) : sizeof(ILibDuktape_WebSocket_Pointers));
@@ -1589,11 +1782,13 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
if (((ILibDuktape_http_request_dataType*)user[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request)
{
ILibDuktape_EventEmitter_CreateEvent(emitter, "response", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnReceive));
ILibDuktape_EventEmitter_CreateEvent(emitter, "continue", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnContinue));
((ILibDuktape_http_requestClient_callbacks*)user[1])->requestStream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_http_request_write, ILibDuktape_http_request_end, token);
((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest = duk_get_heapptr(ctx, -1);
}
else
{
ILibDuktape_EventEmitter_CreateEventEx(emitter, "response");
((ILibDuktape_WebSocket_Pointers*)user[1])->ctx = ctx;
((ILibDuktape_WebSocket_Pointers*)user[1])->clientRequest_ptr = duk_get_heapptr(ctx, -1);
ILibDuktape_CreateInstanceMethod(ctx, "end", ILibDuktape_http_request_no_op, 0);
@@ -2221,23 +2416,6 @@ void ILibDuktape_https_PUSH(duk_context *ctx, void *chain)
ILibDuktape_http_PUSH_EX(ctx, chain, 1);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_onUpgrade(duk_context *ctx)
{
int i, nargs = duk_get_top(ctx);
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [func][digestClientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [func][digestClientRequest][emit]
duk_swap_top(ctx, -2); // [func][emit][this]
duk_push_string(ctx, "upgrade"); // [func][emit][this][upgrade]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][emit][this][upgrade][params]
}
if (duk_pcall_method(ctx, 1 + nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
{
ILibHTTPPacket *packet;
@@ -2258,6 +2436,38 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_onDrain(duk_context *ctx)
{
duk_push_this(ctx); // [clientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [clientRequest][digestClientRequest]
if (duk_has_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS))
{
duk_get_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS);
ILibDuktape_WritableStream_Ready((ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL));
}
}
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_propagateEvent(duk_context *ctx)
{
int i, nargs = duk_get_top(ctx);
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [func][digestClientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [func][digestClientRequest][emit]
duk_swap_top(ctx, -2); // [func][emit][this]
duk_get_prop_string(ctx, -3, CLIENTREQUEST_EVENT_NAME); // [func][emit][this][eventName]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][emit][this][eventName][params]
}
if (duk_pcall_method(ctx, 1 + nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
return(0);
}
extern void* ILibWebClient_Digest_GenerateTable(ILibWebClient_StateObject state);
duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
{
@@ -2283,6 +2493,17 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
if (packet->StatusCode == 401)
{
duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_dup(ctx, -2); // [digestClientRequest][clientRequest][end][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.onResponse(): "); }
duk_pop_2(ctx); // [digestClientRequest]
}
duk_pop(ctx); // ...
// UnAuthorized, need to retry request with Authorization Headers
duk_get_prop_string(ctx, 0, HTTP_INCOMINGMSG_WebStateObject);
wcdo = (ILibWebClient_StateObject)duk_get_pointer(ctx, -1);
@@ -2364,10 +2585,42 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
duk_put_prop_string(ctx, -2, "digestClientRequest"); // [clientReqeust][get][this][options][callback]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digest_onResponse: Error Invoking http.get"); }
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onUpgrade, 3); // [clientReqeust][OnUpgrade]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][OnUpgrade][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][OnUpgrade]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][EventDispatcher]
duk_push_string(ctx, "upgrade"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "upgrade", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][EventDispatcher]
duk_push_string(ctx, "error"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "error", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][EventDispatcher]
duk_push_string(ctx, "continue"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "continue", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [clientReqeust][onDrain]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][onDrain][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][onDrain]
ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "drain", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust]
duk_push_heapptr(ctx, digestClientPtr); // [clientRequest][digestClientRequest]
duk_swap_top(ctx, -2); // [digestClientRequest][clientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest]
}
return(0);
@@ -2397,6 +2650,8 @@ duk_ret_t ILibDuktape_httpDigest_digestRequest_end(duk_context *ctx)
int nargs = duk_get_top(ctx);
int i;
duk_push_this(ctx); // [digestClientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_swap_top(ctx, -2); // [digestClientRequest][end][this]
@@ -2406,8 +2661,67 @@ duk_ret_t ILibDuktape_httpDigest_digestRequest_end(duk_context *ctx)
duk_dup(ctx, i); // [digestClientRequest][end][this][params...]
}
if (duk_pcall_method(ctx, nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
duk_push_this(ctx);
duk_del_prop_string(ctx, -1, "DIGEST_CLIENT_REQUEST");
}
return(0);
}
ILibTransport_DoneState ILibDuktape_httpDigest_http_request_WriteHandler(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibTransport_DoneState retVal = ILibTransport_DoneState_ERROR;
duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "write"); // [digestClientRequest][clientRequest][write]
duk_swap_top(ctx, -2); // [digestClientRequest][write][this]
if (stream->Reserved == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, buffer, (duk_size_t)bufferLen);
}
else
{
duk_push_lstring(ctx, buffer, (duk_size_t)bufferLen);
}
if (duk_pcall_method(ctx, 1) != 0)
{
ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.clientRequest.write(): ");
retVal = ILibTransport_DoneState_ERROR;
}
else
{
retVal = duk_get_boolean(ctx, -1) ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
}
duk_pop(ctx); // [digestClientRequest]
}
duk_pop(ctx); // ...
return(retVal);
}
void ILibDuktape_httpDigest_http_request_DoneHandler(struct ILibDuktape_WritableStream *stream, void *user)
{
duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_swap_top(ctx, -2); // [digestClientRequest][end][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.clientRequest.end(): "); }
duk_pop(ctx); // [digestClientRequest]
duk_del_prop_string(ctx, -1, "DIGEST_CLIENT_REQUEST");
}
duk_pop(ctx); // ...
}
duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
@@ -2449,7 +2763,9 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "response");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_CreateInstanceMethod(ctx, "end", ILibDuktape_httpDigest_digestRequest_end, DUK_VARARGS);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "continue");
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_httpDigest_http_request_WriteHandler, ILibDuktape_httpDigest_http_request_DoneHandler, NULL);
if (nargs > 1 && duk_is_function(ctx, 1))
{
@@ -2463,10 +2779,34 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
// [clientRequest]
duk_push_heapptr(emitter->ctx, emitter->object); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onUpgrade, 3); // [digestClientRequest][OnUpgrade]
duk_dup(ctx, -2); // [digestClientRequest][OnUpgrade][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][OnUpgrade]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "upgrade", duk_get_heapptr(ctx, -1));
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [digestClientRequest][EventDispatcher]
duk_dup(ctx, -2); // [digestClientRequest][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][EventDispatcher]
duk_push_string(ctx, "upgrade"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "upgrade", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher]
duk_pop(ctx); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [digestClientRequest][EventDispatcher]
duk_dup(ctx, -2); // [digestClientRequest][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][EventDispatcher]
duk_push_string(ctx, "error"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "error", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher]
duk_pop(ctx); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [digestClientRequest][EventDispatcher]
duk_dup(ctx, -2); // [digestClientRequest][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][EventDispatcher]
duk_push_string(ctx, "continue"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "continue", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher]
duk_pop(ctx); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [digestClientRequest][onDrain]
duk_dup(ctx, -2); // [digestClientRequest][onDrain][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][onDrain]
ILibDuktape_EventEmitter_AddOn(crEmitter, "drain", duk_get_heapptr(ctx, -1)); // [digestClientRequest][onDrain]
duk_pop(ctx); // [digestClientRequest]
return(1);

View File

@@ -17,8 +17,6 @@
#define ILibDuktape_EventEmitter_Hook ((void*)0xEEEE)
#define ILibDuktape_EventEmitter_GlobalListenerCount "\xFF_EventEmitter_GlobalListenerCount"
void ILibDuktape_EventEmitter_ClearListenersSink(void *chain, void *eventList);
#ifdef __DOXY__
@@ -94,7 +92,14 @@ public:
};
#endif
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr)
{
ILibDuktape_EventEmitter *retVal = NULL;
duk_push_heapptr(ctx, objHeapptr); // [obj]
retVal = ILibDuktape_EventEmitter_GetEmitter(ctx, -1);
duk_pop(ctx); // ...
return(retVal);
}
void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
ILibDuktape_EventEmitter *data = (ILibDuktape_EventEmitter*)user;
@@ -166,8 +171,9 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
int nargs = duk_get_top(ctx);
ILibDuktape_EventEmitter *data;
void *node, *nextNode, *func, *dispatcher;
int i, count;
int i, j, count;
void **hptr;
void **emitList;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
@@ -183,17 +189,19 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, name, (int)nameLen);
if (dispatcher == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Internal Error with event '%s'", name); }
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
#ifdef WIN32
emitList = (void**)_alloca(((unsigned int)ILibLinkedList_GetCount(eventList) + 1) * sizeof(void*));
#else
emitList = (void**)alloca(((unsigned int)ILibLinkedList_GetCount(eventList) + 1) * sizeof(void*));
#endif
node = ILibLinkedList_GetNode_Head(eventList);
i = 0;
while (node != NULL)
{
nextNode = ILibLinkedList_GetNextNode(node);
func = ILibLinkedList_GetDataFromNode(node);
duk_push_heapptr(ctx, func); // [func]
duk_push_heapptr(ctx, self); // [func][this]
for (i = 1; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][this][...args...]
}
emitList[i++] = ILibLinkedList_GetDataFromNode(node);
if (((int*)ILibLinkedList_GetExtendedMemory(node))[0] == 1)
{
@@ -201,15 +209,11 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
ILibLinkedList_Remove(node);
data->totalListeners[0]--;
}
if (duk_pcall_method(ctx, nargs-1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
}
duk_pop(ctx); // ...
node = nextNode;
}
emitList[i] = NULL;
// If no more listeners, we can set the hptr to NULL
if (ILibLinkedList_GetCount(eventList) == 0)
{
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
@@ -224,6 +228,24 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
duk_pop_2(ctx); // ...
}
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
i = 0;
while ((func = emitList[i++]) != NULL)
{
duk_push_heapptr(ctx, func); // [func]
duk_push_heapptr(ctx, self); // [func][this]
for (j = 1; j < nargs; ++j)
{
duk_dup(ctx, j); // [func][this][...args...]
}
if (duk_pcall_method(ctx, nargs - 1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
}
duk_pop(ctx); // ...
}
return 0;
}
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr)
@@ -272,7 +294,10 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
if (eventList == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName)); }
if (eventList == NULL)
{
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
}
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, propName, (int)propNameLen);
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Internal error with Event '%s'", propName)); }
@@ -371,8 +396,7 @@ duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
duk_pop(ctx); // [dispatcher][hptrList]
}
//Use this callback, just in case we were called from an event dispatch. Don't want to clear it during a dispatch, cause we'll crash
ILibChain_RunOnMicrostackThreadEx(Duktape_GetChain(ctx), ILibDuktape_EventEmitter_ClearListenersSink, eventList);
ILibLinkedList_Clear(eventList);
emitter->totalListeners[0] = 0;
}
return(0);
@@ -429,15 +453,12 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
return retVal;
}
void ILibDuktape_EventEmitter_ClearListenersSink(void *chain, void *eventList)
{
ILibLinkedList_Clear(eventList);
}
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler)
{
if (ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, strnlen_s(eventName, 255)) == NULL && handler != NULL)
if (ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255)) == NULL && handler != NULL)
{
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, strnlen_s(eventName, 255), handler);
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255), handler);
}
}
duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
@@ -479,8 +500,7 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
duk_pop(ctx); // [dispatcher][hptrList]
}
//Use this callback, just in case we were called from an event dispatch. Don't want to clear it during a dispatch
ILibChain_RunOnMicrostackThread(Duktape_GetChain(ctx), ILibDuktape_EventEmitter_ClearListenersSink, eventList);
ILibLinkedList_Clear(eventList);
}
else
{
@@ -629,7 +649,7 @@ void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitt
if (heapptr != NULL)
{
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = duk_get_length(emitter->ctx, -1);
count = (int)duk_get_length(emitter->ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(emitter->ctx, -1, i); // [dispatcher][hptrList][hptr]

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);
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,46 +210,18 @@ 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)
{
#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
}
else
{
#if (!defined(_WIN32_WCE) || (defined(_WIN32_WCE) && _WIN32_WCE>=400)) && !defined(NACL)
#ifndef NACL
if (module->UDPServers[i] != NULL)
{
socket = ILibAsyncUDPSocket_GetSocket(module->UDPServers[i]);
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
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;
}
}
}
// Perform a local network broadcast of this packet
@@ -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
@@ -5204,6 +5224,8 @@ struct packetheader* ILibClonePacket(struct packetheader *packet)
// Iterate through each header, and copy them
n = packet->FirstField;
while (n!=NULL)
{
if (ILibHasEntry(packet->HeaderTable, n->Field, n->FieldLength) != 0)
{
ILibAddHeaderLine(
RetVal,
@@ -5211,6 +5233,7 @@ struct packetheader* ILibClonePacket(struct packetheader *packet)
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);
}
}
if (wcdo->IsOrphan != 0 || wcdo->IsWebSocket != 0)
{
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;
}
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);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -6,7 +6,7 @@ export CC=/home/default/Public/ToolChains/LinuxArm/bin/arm-none-linux-gnueabi-gc
cd ../openssl
make clean
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os /g' Makefile > t
rm Makefile

View File

@@ -6,7 +6,7 @@ export CC=arm-linux-gnueabi-gcc
cd ../openssl
make clean
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os /g' Makefile > t
rm Makefile

View File

@@ -6,7 +6,7 @@ export CC=/home/default/Public/ToolChains/ddwrt/4.1.0-uclibc-0.9.28/bin/mipsel-l
cd ../openssl
make clean
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os /g' Makefile > t
rm Makefile

View File

@@ -7,7 +7,7 @@ export PATH=/home/default/Public/PTV1000-GPL/mips-4.3/bin:$PATH
export CC=/home/default/Public/PTV1000-GPL/mips-4.3/bin/mips-linux-gnu-gcc
cd ../openssl
./Configure linux-mipsel no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-mipsel no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os -EL /g' Makefile > t
rm Makefile

View File

@@ -6,7 +6,7 @@ export CC=/home/default/Public/ToolChains/pogoplug-gcc/bin/arm-none-linux-gnueab
cd ../openssl
make clean
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os /g' Makefile > t
rm Makefile

View File

@@ -8,7 +8,7 @@ export CC="/home/default/Public/Galileo/arduino-1.5.3/hardware/tools/sysroots/x8
cd ../openssl
make clean
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic32 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os -m32 /g' Makefile > t
rm Makefile

View File

@@ -8,7 +8,7 @@ export CC="/opt/poky/1.6.1/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-lin
cd ../openssl
make clean
./Configure linux-generic64 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-generic64 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -Os /g' Makefile > t
rm Makefile

View File

@@ -2,7 +2,7 @@
# Copy and run this in the OpenSSL directory for Intel x86 64bit compatible OpenSSL stack
#
cd ../openssl
./Configure linux-x86_64 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-x86_64 no-weak-ssl-ciphers no-srp no-psk no-comp no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -O3 /g' Makefile > t
rm Makefile

View File

@@ -3,7 +3,7 @@
#
cd ../openssl
make clean
./Configure linux-x86 no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-ec no-ecdsa no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
./Configure linux-x86 no-zlib no-zlib-dynamic no-threads no-hw no-err no-dso no-shared -no-asm no-rc5 no-idea no-md4 no-rmd160 no-ssl no-ssl3 no-seed no-camellia no-dso no-bf no-cast no-md2 no-mdc2
make depend
sed 's/ -O3 / -O3 -m32 /g' Makefile > t
rm Makefile