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:
@@ -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
121
Debug/PostDigest.js
Normal 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
120
Debug/WebRTC_Test2.html
Normal 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
134
Debug/WebRTC_Test2.js
Normal 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
70
Debug/exe.js
Normal 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();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ¶mLen, 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); // ...
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user