Much improved Windows MeshAgent stability
Ylian Saint-Hilaire committed
Jan 12, 2018 at 11:41 UTC
f6ef228de6f05986bc4d7de4378bb01bbf3e55e8
15 files changed
+269
-214
MeshCentralServer.njsproj
+2
@@ -28,6 +28,8 @@
28
<Compile Include="amtevents.js" />
29
<Compile Include="amtscanner.js" />
30
<Compile Include="amtscript.js" />
31
+ <Compile Include="letsEncrypt.js" />
32
+ <Compile Include="meshaccelerator.js" />
33
<Compile Include="meshmail.js" />
34
<Compile Include="meshscanner.js" />
35
<Compile Include="certoperations.js" />
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshagent_pi
Binary files a/agents/meshagent_pi and b/agents/meshagent_pi differ
agents/meshcore.js
+21
-9
@@ -472,7 +472,6 @@ function createMeshCore(agent) {
472
473
function onTunnelClosed() {
474
sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
475
- if (this.httprequest.protocol == 1) { this.httprequest.process.end(); delete this.httprequest.process; }
475
delete tunnels[this.httprequest.index];
476
477
/*
@@ -561,7 +560,8 @@ function createMeshCore(agent) {
560
this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
561
this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
562
this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
564
- this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
563
+ this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
564
+ this.prependListener('end', function () { this.httprequest.process.kill(); });
565
}
566
}
567
if (this.httprequest.protocol == 2) {
@@ -717,7 +717,15 @@ function createMeshCore(agent) {
717
var response = null;
718
switch (cmd) {
719
case 'help': { // Displays available commands
720
- response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, parseuri, httpget, wslist,\r\nwsconnect, wssend, wsclose, notify, ls, amt, netinfo, location, power, wakeonlan, scanwifi, scanamt.';
720
+ response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, amt, netinfo, location, power, wakeonlan, scanwifi, scanamt.';
721
+ break;
722
+ }
723
+ case 'eval': { // Eval JavaScript
724
+ if (args['_'].length < 1) {
725
+ response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage
726
+ } else {
727
+ response = JSON.stringify(mesh.eval(args['_'][0]));
728
+ }
729
break;
730
}
731
case 'notify': { // Send a notification message to the mesh
@@ -735,6 +743,7 @@ function createMeshCore(agent) {
743
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nNative Pipes: ' + obj.useNativePipes + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
744
if (amtLmsState >= 0) { response += '\r\nBuilt -in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
745
response += '\r\nModules: ' + JSON.stringify(addedModules) + '';
746
+ response += '\r\nServerConnected: ' + mesh.isControlChannelConnected + '';
747
var oldNodeId = db.Get('OldNodeId');
748
if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
749
response += '\r\ServerState: ' + meshServerConnectionState + '.';
@@ -1136,16 +1145,11 @@ function createMeshCore(agent) {
1145
// Setup the mesh agent event handlers
1146
mesh.AddCommandHandler(handleServerCommand);
1147
mesh.AddConnectHandler(handleServerConnection);
1139
- //mesh.lmsNotification = handleAmtNotification; // TODO
1140
- sendPeriodicServerUpdate(true); // TODO: Check if connected before sending
1141
-
1148
+
1149
// Parse input arguments
1150
//var args = parseArgs(process.argv);
1151
//console.log(args);
1152
1146
- //console.log('Stopping.');
1147
- //process.exit();
1148
-
1153
// Launch LMS
1154
try {
1155
var lme_heci = require('lme_heci');
@@ -1154,6 +1158,14 @@ function createMeshCore(agent) {
1158
amtLms.on('error', function (e) { amtLmsState = 0; amtLms = null; });
1159
amtLms.on('connect', function () { amtLmsState = 2; });
1160
} catch (e) { amtLmsState = -1; amtLms = null; }
1161
+
1162
+ // Check if the control channel is connected
1163
+ if (mesh.isControlChannelConnected) {
1164
+ sendPeriodicServerUpdate(true); // Send the server update
1165
+ }
1166
+
1167
+ //console.log('Stopping.');
1168
+ //process.exit();
1169
}
1170
1171
obj.stop = function () {
agents/modules_meshcmd/amt-scanner.js
+1
-1
@@ -79,7 +79,7 @@ function AMTScanner() {
79
server.bind({ address: '0.0.0.0', port: 0, exclusive: true });
80
var tmout = setTimeout(function cb() {
81
//console.log("Server closed");
82
- //server.close();
82
+ server.close();
83
server.parent.emit('found', server.scanResults);
84
delete server;
85
}, timeout);
agents/modules_meshcmd/lme_heci.js
+90
-130
@@ -21,8 +21,7 @@ var APF_CHANNEL_CLOSE = 97;
21
var APF_PROTOCOLVERSION = 192;
22
23
24
-function lme_object()
25
-{
24
+function lme_object() {
25
this.ourId = ++lme_id;
26
this.amtId = -1;
27
this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
@@ -32,12 +31,11 @@ function lme_object()
31
this.errorCount = 0;
32
}
33
35
-function stream_bufferedWrite()
36
-{
34
+function stream_bufferedWrite() {
35
var emitterUtils = require('events').inherits(this);
36
this.buffer = [];
37
this._readCheckImmediate = undefined;
40
-
38
+
39
// Writable Events
40
emitterUtils.createEvent('close');
41
emitterUtils.createEvent('drain');
@@ -45,21 +43,17 @@ function stream_bufferedWrite()
43
emitterUtils.createEvent('finish');
44
emitterUtils.createEvent('pipe');
45
emitterUtils.createEvent('unpipe');
48
-
46
+
47
// Readable Events
48
emitterUtils.createEvent('readable');
51
- this.isEmpty = function ()
52
- {
49
+ this.isEmpty = function () {
50
return (this.buffer.length == 0);
51
};
55
- this.isWaiting = function ()
56
- {
52
+ this.isWaiting = function () {
53
return (this._readCheckImmediate == undefined);
54
};
59
- this.write = function (chunk)
60
- {
61
- for (var args in arguments)
62
- {
55
+ this.write = function (chunk) {
56
+ for (var args in arguments) {
57
if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; }
58
}
59
var tmp = Buffer.alloc(chunk.length);
@@ -68,41 +62,34 @@ function stream_bufferedWrite()
62
this.emit('readable');
63
return (this.buffer.length == 0 ? true : false);
64
};
71
- this.read = function ()
72
- {
65
+ this.read = function () {
66
var size = arguments.length == 0 ? undefined : arguments[0];
67
var bytesRead = 0;
68
var list = [];
76
- while((size == undefined || bytesRead < size) && this.buffer.length > 0)
77
- {
69
+ while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
70
var len = this.buffer[0].data.length - this.buffer[0].offset;
71
var offset = this.buffer[0].offset;
80
-
81
- if(len > (size - bytesRead))
82
- {
72
+
73
+ if (len > (size - bytesRead)) {
74
// Only reading a subset
75
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
76
this.buffer[0].offset += (size - bytesRead);
77
bytesRead += (size - bytesRead);
78
}
88
- else
89
- {
79
+ else {
80
// Reading the entire thing
81
list.push(this.buffer[0].data.slice(offset));
82
bytesRead += len;
83
this.buffer.shift();
84
}
85
}
96
- this._readCheckImmediate = setImmediate(function (buffered)
97
- {
86
+ this._readCheckImmediate = setImmediate(function (buffered) {
87
buffered._readCheckImmediate = undefined;
99
- if(buffered.buffer.length == 0)
100
- {
88
+ if (buffered.buffer.length == 0) {
89
// drained
90
buffered.emit('drain');
91
}
104
- else
105
- {
92
+ else {
93
// not drained
94
buffered.emit('readable');
95
}
@@ -112,38 +99,33 @@ function stream_bufferedWrite()
99
}
100
101
115
-function lme_heci()
116
-{
102
+function lme_heci() {
103
var emitterUtils = require('events').inherits(this);
104
emitterUtils.createEvent('error');
105
emitterUtils.createEvent('connect');
120
-
106
+
107
var heci = require('heci');
108
this.INITIAL_RXWINDOW_SIZE = 4096;
123
-
109
+
110
this._LME = heci.create();
111
this._LME.LMS = this;
126
- this._LME.on('error', function (e) { this.Parent.emit('error', e); });
127
- this._LME.on('connect', function ()
128
- {
112
+ this._LME.on('error', function (e) { this.LMS.emit('error', e); });
113
+ this._LME.on('connect', function () {
114
this.LMS.emit('connect');
130
- this.on('data', function (chunk)
131
- {
115
+ this.on('data', function (chunk) {
116
// this = HECI
117
var cmd = chunk.readUInt8(0);
134
-
135
- switch(cmd)
136
- {
118
+
119
+ switch (cmd) {
120
default:
121
//console.log('Received ' + chunk.length + ' bytes of data for LMS');
122
//console.log('Command = ' + cmd);
123
break;
141
- case APF_SERVICE_REQUEST:
124
+ case APF_SERVICE_REQUEST:
125
var nameLen = chunk.readUInt32BE(1);
126
var name = chunk.slice(5, nameLen + 5);
127
//console.log("Service Request for: " + name);
145
- if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com')
146
- {
128
+ if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
129
var outBuffer = Buffer.alloc(5 + nameLen);
130
outBuffer.writeUInt8(6, 0);
131
outBuffer.writeUInt32BE(nameLen, 1);
@@ -151,30 +133,26 @@ function lme_heci()
133
this.write(outBuffer);
134
//console.log('Answering APF_SERVICE_REQUEST');
135
}
154
- else
155
- {
136
+ else {
137
//console.log('UNKNOWN APF_SERVICE_REQUEST');
138
}
139
break;
159
- case APF_GLOBAL_REQUEST:
140
+ case APF_GLOBAL_REQUEST:
141
var nameLen = chunk.readUInt32BE(1);
142
var name = chunk.slice(5, nameLen + 5).toString();
143
163
- switch(name)
164
- {
144
+ switch (name) {
145
case 'tcpip-forward':
146
var len = chunk.readUInt32BE(nameLen + 6);
147
var port = chunk.readUInt32BE(nameLen + 10 + len);
148
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
169
- if (this[name] == undefined)
170
- {
149
+ if (this[name] == undefined) {
150
this[name] = {};
151
}
152
this[name][port] = require('net').createServer();
153
this[name][port].HECI = this;
154
this[name][port].listen({ port: port });
176
- this[name][port].on('connection', function (socket)
177
- {
155
+ this[name][port].on('connection', function (socket) {
156
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
157
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort);
158
});
@@ -192,54 +170,48 @@ function lme_heci()
170
break;
171
}
172
break;
195
- case APF_CHANNEL_OPEN_CONFIRMATION:
196
- var rChannel = chunk.readUInt32BE(1);
197
- var sChannel = chunk.readUInt32BE(5);
198
- var wSize = chunk.readUInt32BE(9);
199
- //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
200
- if (this.sockets[rChannel] != undefined)
201
- {
202
- this.sockets[rChannel].lme.amtId = sChannel;
203
- this.sockets[rChannel].lme.rxWindow = wSize;
204
- this.sockets[rChannel].lme.txWindow = wSize;
205
- this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
206
- //console.log('LME_CS_CONNECTED');
207
- this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
208
- this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
209
- this.sockets[rChannel].bufferedStream.on('readable', function ()
210
- {
211
- if(this.socket.lme.txWindow > 0)
212
- {
213
- var buffer = this.read(this.socket.lme.txWindow);
214
- var packet = Buffer.alloc(9 + buffer.length);
215
- packet.writeUInt8(APF_CHANNEL_DATA, 0);
216
- packet.writeUInt32BE(this.socket.lme.amtId, 1);
217
- packet.writeUInt32BE(buffer.length, 5);
218
- buffer.copy(packet, 9);
219
- this.socket.lme.txWindow -= buffer.length;
220
- this.socket.HECI.write(packet);
221
- }
222
- });
223
- this.sockets[rChannel].bufferedStream.on('drain', function ()
224
- {
225
- this.socket.resume();
226
- });
227
- this.sockets[rChannel].on('data', function (chunk)
228
- {
229
- if (!this.bufferedStream.write(chunk)) { this.pause(); }
230
- });
231
- this.sockets[rChannel].on('end', function ()
232
- {
233
- var outBuffer = Buffer.alloc(5);
234
- outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
235
- outBuffer.writeUInt32BE(this.lme.amtId, 1);
236
- this.HECI.write(outBuffer);
237
- });
238
- this.sockets[rChannel].resume();
239
- }
240
-
241
- break;
242
- case APF_PROTOCOLVERSION:
173
+ case APF_CHANNEL_OPEN_CONFIRMATION:
174
+ var rChannel = chunk.readUInt32BE(1);
175
+ var sChannel = chunk.readUInt32BE(5);
176
+ var wSize = chunk.readUInt32BE(9);
177
+ //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
178
+ if (this.sockets[rChannel] != undefined) {
179
+ this.sockets[rChannel].lme.amtId = sChannel;
180
+ this.sockets[rChannel].lme.rxWindow = wSize;
181
+ this.sockets[rChannel].lme.txWindow = wSize;
182
+ this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
183
+ //console.log('LME_CS_CONNECTED');
184
+ this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
185
+ this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
186
+ this.sockets[rChannel].bufferedStream.on('readable', function () {
187
+ if (this.socket.lme.txWindow > 0) {
188
+ var buffer = this.read(this.socket.lme.txWindow);
189
+ var packet = Buffer.alloc(9 + buffer.length);
190
+ packet.writeUInt8(APF_CHANNEL_DATA, 0);
191
+ packet.writeUInt32BE(this.socket.lme.amtId, 1);
192
+ packet.writeUInt32BE(buffer.length, 5);
193
+ buffer.copy(packet, 9);
194
+ this.socket.lme.txWindow -= buffer.length;
195
+ this.socket.HECI.write(packet);
196
+ }
197
+ });
198
+ this.sockets[rChannel].bufferedStream.on('drain', function () {
199
+ this.socket.resume();
200
+ });
201
+ this.sockets[rChannel].on('data', function (chunk) {
202
+ if (!this.bufferedStream.write(chunk)) { this.pause(); }
203
+ });
204
+ this.sockets[rChannel].on('end', function () {
205
+ var outBuffer = Buffer.alloc(5);
206
+ outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
207
+ outBuffer.writeUInt32BE(this.lme.amtId, 1);
208
+ this.HECI.write(outBuffer);
209
+ });
210
+ this.sockets[rChannel].resume();
211
+ }
212
+
213
+ break;
214
+ case APF_PROTOCOLVERSION:
215
var major = chunk.readUInt32BE(1);
216
var minor = chunk.readUInt32BE(5);
217
var reason = chunk.readUInt32BE(9);
@@ -254,16 +226,13 @@ function lme_heci()
226
case APF_CHANNEL_WINDOW_ADJUST:
227
var rChannelId = chunk.readUInt32BE(1);
228
var bytesToAdd = chunk.readUInt32BE(5);
257
- if (this.sockets[rChannelId] != undefined)
258
- {
229
+ if (this.sockets[rChannelId] != undefined) {
230
this.sockets[rChannelId].lme.txWindow += bytesToAdd;
260
- if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting())
261
- {
231
+ if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
232
this.sockets[rChannelId].bufferedStream.emit('readable');
233
}
234
}
265
- else
266
- {
235
+ else {
236
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
237
}
238
break;
@@ -271,11 +240,9 @@ function lme_heci()
240
var rChannelId = chunk.readUInt32BE(1);
241
var dataLen = chunk.readUInt32BE(5);
242
var data = chunk.slice(9, 9 + dataLen);
274
- if (this.sockets[rChannelId] != undefined)
275
- {
243
+ if (this.sockets[rChannelId] != undefined) {
244
this.sockets[rChannelId].pendingBytes.push(data.length);
277
- this.sockets[rChannelId].write(data, function ()
278
- {
245
+ this.sockets[rChannelId].write(data, function () {
246
var written = this.pendingBytes.shift();
247
var outBuffer = Buffer.alloc(9);
248
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
@@ -284,35 +251,31 @@ function lme_heci()
251
this.HECI.write(outBuffer);
252
});
253
}
287
- else
288
- {
254
+ else {
255
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
256
}
257
break;
258
case APF_CHANNEL_CLOSE:
259
var rChannelId = chunk.readUInt32BE(1);
294
- if (this.sockets[rChannelId] != undefined)
295
- {
296
- this.sockets[rChannelId].end();
260
+ if (this.sockets[rChannelId] != undefined) {
261
+ this.sockets[rChannelId].end();
262
var amtId = this.sockets[rChannelId].lme.amtId;
263
var buffer = Buffer.alloc(5);
264
delete this.sockets[rChannelId];
300
-
265
+
266
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
267
buffer.writeUInt32BE(amtId, 1);
268
this.write(buffer);
269
}
305
- else
306
- {
270
+ else {
271
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
272
}
273
break;
274
}
275
});
276
});
313
-
314
- this.bindDuplexStream = function (duplexStream, remoteFamily, localPort)
315
- {
277
+
278
+ this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
279
var socket = duplexStream;
280
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
281
socket.pendingBytes = [];
@@ -327,19 +290,16 @@ function lme_heci()
290
buffer.writeUInt32BE(socket.lme.ourId);
291
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
292
buffer.writeUInt32BE(0xFFFFFFFF);
330
- for (var i = 0; i < 2; ++i)
331
- {
332
- if (remoteFamily == 'IPv6')
333
- {
293
+ for (var i = 0; i < 2; ++i) {
294
+ if (remoteFamily == 'IPv6') {
295
buffer.writeUInt32BE(3);
296
buffer.write('::1');
297
}
337
- else
338
- {
298
+ else {
299
buffer.writeUInt32BE(9);
300
buffer.write('127.0.0.1');
301
}
342
-
302
+
303
buffer.writeUInt32BE(localPort);
304
}
305
this._LME.write(buffer.buffer);
@@ -347,7 +307,7 @@ function lme_heci()
307
this._LME.sockets[socket.lme.ourId] = socket;
308
socket.pause();
309
};
350
-
310
+
311
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
312
}
313
agents/modules_meshcore/amt-scanner.js
+1
-1
@@ -79,7 +79,7 @@ function AMTScanner() {
79
server.bind({ address: '0.0.0.0', port: 0, exclusive: true });
80
var tmout = setTimeout(function cb() {
81
//console.log("Server closed");
82
- //server.close();
82
+ server.close();
83
server.parent.emit('found', server.scanResults);
84
if (func != null) { func(server.scanResults); }
85
delete server;
agents/modules_meshcore/lme_heci.js
+1
-1
@@ -123,7 +123,7 @@ function lme_heci()
123
124
this._LME = heci.create();
125
this._LME.LMS = this;
126
- this._LME.on('error', function (e) { this.Parent.emit('error', e); });
126
+ this._LME.on('error', function (e) { this.LMS.emit('error', e); });
127
this._LME.on('connect', function ()
128
{
129
this.LMS.emit('connect');
certoperations.js
+25
-20
@@ -11,6 +11,7 @@ module.exports.CertificateOperations = function () {
11
12
obj.fs = require('fs');
13
obj.forge = require('node-forge');
14
+ obj.crypto = require('crypto');
15
obj.pki = obj.forge.pki;
16
obj.dirExists = function (filePath) { try { return obj.fs.statSync(filePath).isDirectory(); } catch (err) { return false; } }
17
obj.getFilesizeInBytes = function(filename) { try { return obj.fs.statSync(filename)["size"]; } catch (err) { return -1; } }
@@ -412,52 +413,56 @@ module.exports.CertificateOperations = function () {
413
return r;
414
}
415
415
- // Start accelerators
416
+ // Accelerators, used to dispatch work to other processes
417
const fork = require('child_process').fork;
417
- const program = require('path').resolve('meshaccelerator.js');
418
- const acceleratorCreateCount = require('os').cpus().length;
418
+ const program = require('path').join(__dirname, 'meshaccelerator.js');
419
+ const acceleratorTotalCount = require('os').cpus().length;
420
+ var acceleratorCreateCount = acceleratorTotalCount;
421
var freeAccelerators = [];
422
+ var pendingAccelerator = [];
423
+ obj.acceleratorCertStore = null;
424
425
// Create a new accelerator module
422
- obj.getAccelerator = function() {
426
+ obj.getAccelerator = function () {
427
+ if (obj.acceleratorCertStore == null) { return null; }
428
if (freeAccelerators.length > 0) { return freeAccelerators.pop(); }
429
if (acceleratorCreateCount > 0) {
430
+ acceleratorCreateCount--;
431
var accelerator = fork(program, [], { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] });
426
- accelerator.on('message', function (message) { this.func(message); freeAccelerators.push(this); });
427
- if (obj.acceleratorCertStore != null) { accelerator.send({ action: 'setState', certs: obj.acceleratorCertStore }); }
432
+ accelerator.on('message', function (message) { this.func(message); if (pendingAccelerator.length > 0) { accelerator.send(pendingAccelerator.shift()); } else { freeAccelerators.push(this); } });
433
+ accelerator.send({ action: 'setState', certs: obj.acceleratorCertStore });
434
return accelerator;
435
}
436
return null;
437
}
438
439
// Set the state of the accelerators. This way, we don't have to send certificate & keys to them each time.
434
- obj.acceleratorCertStore = null;
435
- obj.acceleratorPerformSetState = function (certificates) {
440
+ obj.acceleratorStart = function (certificates) {
441
+ if (obj.acceleratorCertStore != null) { console.error('ERROR: Accelerators can only be started once.'); return; }
442
obj.acceleratorCertStore = [{ cert: certificates.agent.cert, key: certificates.agent.key }];
443
if (certificates.swarmserver != null) { obj.acceleratorCertStore.push({ cert: certificates.swarmserver.cert, key: certificates.swarmserver.key }); }
444
}
445
446
// Perform any RSA signature, just pass in the private key and data.
447
obj.acceleratorPerformSignature = function (privatekey, data, func) {
442
- var acc = obj.getAccelerator();
443
- if (acc == null) {
448
+ if (acceleratorTotalCount <= 1) {
449
// No accelerators available
450
if (typeof privatekey == 'number') { privatekey = obj.acceleratorCertStore[privatekey].key; }
446
- const sign = crypto.createSign('SHA384');
451
+ const sign = obj.crypto.createSign('SHA384');
452
sign.end(new Buffer(data, 'binary'));
453
func(sign.sign(privatekey).toString('binary'));
454
} else {
450
- // Use the accelerator
451
- acc.func = func;
452
- acc.send({ action: 'sign', key: privatekey, data: data });
455
+ var acc = obj.getAccelerator();
456
+ if (acc == null) {
457
+ // Add to pending accelerator workload
458
+ pendingAccelerator.push({ action: 'sign', key: privatekey, data: data });
459
+ } else {
460
+ // Send to accelerator now
461
+ acc.func = func;
462
+ acc.send({ action: 'sign', key: privatekey, data: data });
463
+ }
464
}
465
}
466
456
- // Perform a RSA signature. This is time consuming
457
- obj.acceleratorPerformVerify = function (publickey, data, msg, func) {
458
- console.log('Performing verification...');
459
- func(publickey.verify(data, msg));
460
- }
461
-
467
return obj;
468
};
letsEncrypt.js
new
+81
@@ -0,0 +1,81 @@
1
+/**
2
+* @description MeshCentral letsEncrypt module
3
+* @author Ylian Saint-Hilaire
4
+* @copyright Intel Corporation 2018
5
+* @license Apache-2.0
6
+* @version v0.0.1
7
+*/
8
+
9
+module.exports.CreateLetsEncrypt = function (parent) {
10
+ var obj = {};
11
+ obj.parent = parent;
12
+ obj.webrootPath = obj.parent.path.join(obj.parent.datapath, 'acme-challenges');
13
+ obj.workPath = obj.parent.path.join(obj.parent.datapath, 'acme-challenges', 'work');
14
+ obj.logsPath = obj.parent.path.join(obj.parent.datapath, 'acme-challenges', 'logs');
15
+
16
+ try { obj.parent.fs.mkdirSync(obj.webrootPath); } catch (e) { }
17
+ try { obj.parent.fs.mkdirSync(obj.workPath); } catch (e) { }
18
+ try { obj.parent.fs.mkdirSync(obj.logsPath); } catch (e) { }
19
+
20
+ console.log('CreateLetsEncrypt-1', obj.webrootPath);
21
+ console.log('CreateLetsEncrypt-1', obj.workPath);
22
+ console.log('CreateLetsEncrypt-1', obj.logsPath);
23
+
24
+ obj.lex = require('greenlock-express').create({
25
+ // Set to https://acme-v01.api.letsencrypt.org/directory in production
26
+ server: 'staging'
27
+
28
+ // If you wish to replace the default plugins, you may do so here
29
+ , challenges: {
30
+ 'http-01': require('le-challenge-fs').create({ webrootPath: obj.webrootPath })
31
+ }
32
+ , store: require('le-store-certbot').create({
33
+ //configDir: '/etc/letsencrypt',
34
+ //privkeyPath: ':configDir/live/:hostname/privkey.pem',
35
+ //fullchainPath: ':configDir/live/:hostname/fullchain.pem',
36
+ //certPath: ':configDir/live/:hostname/cert.pem',
37
+ //chainPath: ':configDir/live/:hostname/chain.pem',
38
+ workDir: obj.workPath,
39
+ logsDir: obj.logsPath,
40
+ webrootPath: obj.webrootPath,
41
+ debug: false
42
+ })
43
+ , approveDomains: approveDomains
44
+ });
45
+
46
+ console.log('CreateLetsEncrypt-2');
47
+ function approveDomains(opts, certs, func) {
48
+ console.log('approveDomains', opts, certs);
49
+
50
+ // This is where you check your database and associated
51
+ // email addresses with domains and agreements and such
52
+
53
+
54
+ // The domains being approved for the first time are listed in opts.domains
55
+ // Certs being renewed are listed in certs.altnames
56
+ if (certs) {
57
+ opts.domains = ['example.com', 'yourdomain.com']
58
+ } else {
59
+ opts.email = 'john.doe@example.com';
60
+ opts.agreeTos = true;
61
+ }
62
+
63
+ // NOTE: you can also change other options such as `challengeType` and `challenge`
64
+ // opts.challengeType = 'http-01';
65
+ // opts.challenge = require('le-challenge-fs').create({});
66
+
67
+ func(null, { options: opts, certs: certs });
68
+ }
69
+
70
+ // Handles acme-challenge and redirects to https
71
+ require('http').createServer(obj.lex.middleware(require('redirect-https')())).listen(81, function () { console.log("Listening for ACME http-01 challenges on", this.address()); });
72
+
73
+ var app = require('express')();
74
+ app.use('/', function (req, res) { res.end('Hello, World!'); });
75
+
76
+ // Handles your app
77
+ require('https').createServer(obj.lex.httpsOptions, obj.lex.middleware(app)).listen(443, function () { console.log("Listening for ACME tls-sni-01 challenges and serve app on", this.address()); });
78
+
79
+ console.log('CreateLetsEncrypt-3');
80
+ return obj;
81
+}
\ No newline at end of file
meshagent.js
+10
-12
@@ -170,7 +170,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
170
obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.parent.swarmCertificateAsn1.length) + obj.parent.swarmCertificateAsn1 + signature); // Command 2, certificate + signature
171
});
172
} else {
173
- // Perform the hash signature using new server agent certificate
173
+ // Perform the hash signature using the server agent certificate
174
obj.parent.parent.certificateOperations.acceleratorPerformSignature(0, msg.substring(2) + obj.nonce, function (signature) {
175
// Send back our certificate + signature
176
obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.parent.agentCertificateAsn1.length) + obj.parent.agentCertificateAsn1 + signature); // Command 2, certificate + signature
@@ -190,9 +190,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
190
// Decode the certificate
191
var certlen = obj.common.ReadShort(msg, 2);
192
obj.unauth = {};
193
- obj.unauth.nodeCert = null;
194
- try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
195
- obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
193
+ try { obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))).publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); } catch (e) { return; }
194
+ obj.unauth.nodeCertPem = '-----BEGIN CERTIFICATE-----\r\n' + new Buffer(msg.substring(4, 4 + certlen), 'binary').toString('base64') + '\r\n-----END CERTIFICATE-----';
195
196
// Check the agent signature if we can
197
if (obj.agentnonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processAgentSignature(msg.substring(4 + certlen)) == false) { console.log('Agent connected with bad signature, holding connection (' + obj.remoteaddr + ').'); return; } }
@@ -237,7 +236,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
236
237
// Start authenticate the mesh agent by sending a auth nonce & server TLS cert hash.
238
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
240
- obj.nonce = obj.forge.random.getBytesSync(48);
239
+ obj.nonce = obj.parent.crypto.randomBytes(48).toString('binary');
240
obj.send(obj.common.ShortToStr(1) + getWebCertHash(obj.domain) + obj.nonce); // Command 1, hash + nonce
241
242
// Once we get all the information about an agent, run this to hook everything up to the server
@@ -357,18 +356,17 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
356
357
// Get the web certificate hash for the speficied domain
358
function getWebCertHash(domain) {
360
- //var hash = obj.parent.webCertificateHashs[domain.id];
361
- //if (hash == null) return obj.parent.webCertificateHash; else return hash;
359
+ var hash = obj.parent.webCertificateHashs[domain.id];
360
+ if (hash != null) return hash;
361
return obj.parent.webCertificateHash;
362
}
363
364
// Verify the agent signature
365
function processAgentSignature(msg) {
367
- var md = obj.forge.md.sha384.create(); // TODO: Switch this to SHA384 on node instead of forge.
368
- md.update(getWebCertHash(obj.domain), 'binary');
369
- md.update(obj.nonce, 'binary');
370
- md.update(obj.agentnonce, 'binary');
371
- if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; } // TODO: Check if this is slow or not. May n
366
+ // Verify the signature. This is the fast way, without using forge.
367
+ const verify = obj.parent.crypto.createVerify('SHA384');
368
+ verify.end(new Buffer(getWebCertHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary'));
369
+ if (verify.verify(obj.unauth.nodeCertPem, new Buffer(msg, 'binary')) !== true) { return false; }
370
371
// Connection is a success, clean up
372
obj.nodeid = obj.unauth.nodeid;
meshcentral.js
+1
-1
@@ -314,7 +314,7 @@ function CreateMeshCentralServer() {
314
obj.certificateOperations = require('./certoperations.js').CertificateOperations()
315
obj.certificateOperations.GetMeshServerCertificate(obj.datapath, obj.args, obj.config, function (certs) {
316
obj.certificates = certs;
317
- obj.certificateOperations.acceleratorPerformSetState(certs); // Set the state of the accelerators
317
+ obj.certificateOperations.acceleratorStart(certs); // Set the state of the accelerators
318
319
// If the certificate is un-configured, force LAN-only mode
320
if (obj.certificates.CommonName == 'un-configured') { console.log('Server name not configured, running in LAN-only mode.'); obj.args.lanonly = true; }
multiserver.js
+35
-38
@@ -29,7 +29,6 @@ module.exports.CreateMultiServer = function (parent, args) {
29
obj.common = require('./common.js');
30
obj.forge = require('node-forge');
31
obj.crypto = require('crypto');
32
- obj.pki = obj.forge.pki;
32
obj.connectionState = 0;
33
obj.retryTimer = null;
34
obj.retryBackoff = 0;
@@ -64,7 +63,7 @@ module.exports.CreateMultiServer = function (parent, args) {
63
obj.ws.on('open', function () {
64
obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Connected');
65
obj.connectionState |= 2;
67
- obj.nonce = obj.forge.random.getBytesSync(48);
66
+ obj.nonce = obj.crypto.randomBytes(48).toString('binary');
67
68
// Get the peer server's certificate and compute the server public key hash
69
if (obj.ws._socket == null) return;
@@ -94,30 +93,27 @@ module.exports.CreateMultiServer = function (parent, args) {
93
if (obj.serverCertHash != msg.substring(2, 50)) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
94
obj.servernonce = msg.substring(50);
95
97
- // Use our agent certificate root private key to sign the ServerHash + ServerNonce + PeerNonce
98
- var md = obj.forge.md.sha384.create();
99
- md.update(msg.substring(2), 'binary');
100
- md.update(obj.nonce, 'binary');
96
+ // Perform the hash signature using the server agent certificate
97
+ obj.parent.parent.certificateOperations.acceleratorPerformSignature(0, msg.substring(2) + obj.nonce, function (signature) {
98
+ // Send back our certificate + signature
99
+ obj.ws.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.agentCertificateAsn1.length) + obj.agentCertificateAsn1 + signature); // Command 2, certificate + signature
100
+ });
101
102
- // Send back our certificate + signature
103
- agentRootCertificateAsn1 = obj.forge.asn1.toDer(obj.forge.pki.certificateToAsn1(obj.certificates.agent.fcert)).getBytes();
104
- obj.ws.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(agentRootCertificateAsn1.length) + agentRootCertificatAsn1 + obj.certificates.agent.fkey.sign(md)); // Command 3, signature
102
break;
103
}
104
case 2: {
105
// Server certificate
106
var certlen = obj.common.ReadShort(msg, 2), serverCert = null;
107
+ var serverCertPem = '-----BEGIN CERTIFICATE-----\r\n' + new Buffer(msg.substring(4, 4 + certlen), 'binary').toString('base64') + '\r\n-----END CERTIFICATE-----';
108
try { serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { }
109
if (serverCert == null) { obj.parent.parent.debug(1, 'OutPeer: Invalid server certificate.'); disconnect(); return; }
110
var serverid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
111
if (serverid !== obj.agentCertificateHashBase64) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
112
115
- // Server signature, verify it
116
- var md = obj.forge.md.sha384.create();
117
- md.update(obj.serverCertHash, 'binary');
118
- md.update(obj.nonce, 'binary');
119
- md.update(obj.servernonce, 'binary');
120
- if (serverCert.publicKey.verify(md.digest().bytes(), msg.substring(4 + certlen)) == false) { obj.parent.parent.debug(1, 'OutPeer: Server sign check failed.'); disconnect(); return; }
113
+ // Server signature, verify it. This is the fast way, without using forge. (TODO: Use accelerator for this?)
114
+ const verify = obj.parent.crypto.createVerify('SHA384');
115
+ verify.end(new Buffer(obj.serverCertHash + obj.nonce + obj.servernonce, 'binary'));
116
+ if (verify.verify(serverCertPem, new Buffer(msg.substring(4 + certlen), 'binary')) !== true) { obj.parent.parent.debug(1, 'OutPeer: Server sign check failed.'); disconnect(); return; }
117
118
// Connection is a success, clean up
119
delete obj.nonce;
@@ -128,14 +124,14 @@ module.exports.CreateMultiServer = function (parent, args) {
124
obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Verified peer connection to ' + obj.url);
125
126
// Send information about our server to the peer
131
- if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.webserver.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
127
+ if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
128
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
129
break;
130
}
131
case 4: {
132
// Server confirmed authentication, we are allowed to send commands to the server
133
obj.connectionState |= 8;
138
- if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.webserver.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
134
+ if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 })); }
135
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
136
break;
137
}
@@ -258,15 +254,13 @@ module.exports.CreateMultiServer = function (parent, args) {
254
255
// Check that the server hash matches out own web certificate hash
256
if (obj.webCertificateHash != msg.substring(2, 50)) { obj.close(); return; }
261
-
262
- // Use our server private key to sign the ServerHash + PeerNonce + ServerNonce
263
- var md = obj.forge.md.sha384.create();
264
- md.update(msg.substring(2), 'binary');
265
- md.update(obj.nonce, 'binary');
257
obj.peernonce = msg.substring(50);
258
268
- // Send back our certificate + signature
269
- obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.agentCertificateAsn1.length) + obj.agentCertificateAsn1 + obj.parent.parent.certificates.agent.fkey.sign(md)); // Command 2, certificate + signature
259
+ // Perform the hash signature using the server agent certificate
260
+ obj.parent.parent.certificateOperations.acceleratorPerformSignature(0, msg.substring(2) + obj.nonce, function (signature) {
261
+ // Send back our certificate + signature
262
+ obj.send(obj.common.ShortToStr(2) + obj.common.ShortToStr(obj.agentCertificateAsn1.length) + obj.agentCertificateAsn1 + signature); // Command 2, certificate + signature
263
+ });
264
265
// Check the peer server signature if we can
266
if (obj.unauthsign != null) {
@@ -275,22 +269,25 @@ module.exports.CreateMultiServer = function (parent, args) {
269
}
270
else if (cmd == 2) {
271
// Peer server certificate
278
- if ((msg.length < 4) || ((obj.receivedCommands & 2) != 0)) return;
272
+ if ((msg.length < 4) || ((obj.receivedCommands & 2) != 0)) { obj.parent.parent.debug(1, 'InPeer: Invalid command 2.'); return; }
273
obj.receivedCommands += 2; // Peer server can't send the same command twice on the same connection ever. Block DOS attack path.
274
275
// Decode the certificate
276
var certlen = obj.common.ReadShort(msg, 2);
277
obj.unauth = {};
284
- obj.unauth.nodeCert = null;
285
- try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
286
- obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
278
+ try { obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))).publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); } catch (e) { console.log(e); return; }
279
+ obj.unauth.nodeCertPem = '-----BEGIN CERTIFICATE-----\r\n' + new Buffer(msg.substring(4, 4 + certlen), 'binary').toString('base64') + '\r\n-----END CERTIFICATE-----';
280
281
// Check the peer server signature if we can
289
- if (obj.peernonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processPeerSignature(msg.substring(4 + certlen)) == false) { obj.close(); return; } }
282
+ if (obj.peernonce == null) {
283
+ obj.unauthsign = msg.substring(4 + certlen);
284
+ } else {
285
+ if (processPeerSignature(msg.substring(4 + certlen)) == false) { obj.parent.parent.debug(1, 'InPeer: Invalid signature.'); obj.close(); return; }
286
+ }
287
completePeerServerConnection();
288
}
289
else if (cmd == 3) {
293
- if ((msg.length < 56) || ((obj.receivedCommands & 4) != 0)) return;
290
+ if ((msg.length < 56) || ((obj.receivedCommands & 4) != 0)) { obj.parent.parent.debug(1, 'InPeer: Invalid command 3.'); return; }
291
obj.receivedCommands += 4; // Peer server can't send the same command twice on the same connection ever. Block DOS attack path.
292
completePeerServerConnection();
293
}
@@ -306,25 +303,24 @@ module.exports.CreateMultiServer = function (parent, args) {
303
304
// Start authenticate the peer server by sending a auth nonce & server TLS cert hash.
305
// Send 384 bits SHA382 hash of TLS cert public key + 384 bits nonce
309
- obj.nonce = obj.forge.random.getBytesSync(48);
306
+ obj.nonce = obj.crypto.randomBytes(48).toString('binary');
307
obj.send(obj.common.ShortToStr(1) + obj.webCertificateHash + obj.nonce); // Command 1, hash + nonce
308
309
// Once we get all the information about an peer server, run this to hook everything up to the server
310
function completePeerServerConnection() {
311
if (obj.authenticated != 1) return;
312
obj.send(obj.common.ShortToStr(4));
316
- obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.webserver.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 }));
313
+ obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificateHashBase64 }));
314
obj.authenticated = 2;
315
}
316
317
// Verify the peer server signature
318
function processPeerSignature(msg) {
322
- var md = obj.forge.md.sha384.create(); // TODO: Switch this to SHA384 on node instead of forge.
323
- md.update(obj.parent.parent.webserver.webCertificateHash, 'binary');
324
- md.update(obj.nonce, 'binary');
325
- md.update(obj.peernonce, 'binary');
326
- if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
327
- if (obj.unauth.nodeid !== obj.agentCertificateHashBase64) { return false; }
319
+ // Verify the signature. This is the fast way, without using forge.
320
+ const verify = obj.parent.crypto.createVerify('SHA384');
321
+ verify.end(new Buffer(obj.parent.parent.webserver.webCertificateHash + obj.nonce + obj.peernonce, 'binary'));
322
+ if (verify.verify(obj.unauth.nodeCertPem, new Buffer(msg, 'binary')) !== true) { console.log('Peer sign fail 1'); return false; }
323
+ if (obj.unauth.nodeid !== obj.agentCertificateHashBase64) { console.log('Peer sign fail 2'); return false; }
324
325
// Connection is a success, clean up
326
obj.nodeid = obj.unauth.nodeid;
@@ -333,6 +329,7 @@ module.exports.CreateMultiServer = function (parent, args) {
329
delete obj.unauth;
330
if (obj.unauthsign) delete obj.unauthsign;
331
obj.authenticated = 1;
332
+
333
return true;
334
}
335
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.1.2-b",
3
+ "version": "0.1.2-h",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",