Fixed multi-tenancy DNS support

This commit is contained in:
Ylian Saint-Hilaire 2018-01-04 12:15:21 -08:00
parent eb363f0cee
commit d455e35658
24 changed files with 167 additions and 110 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1,11 @@
/* /*
Copyright 2017 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -67,7 +67,7 @@ function createMeshCore(agent) {
db = require('SimpleDataStore').Shared(); db = require('SimpleDataStore').Shared();
sha = require('SHA256Stream'); sha = require('SHA256Stream');
mesh = require('MeshAgent'); mesh = require('MeshAgent');
processManager = require('ILibProcessPipe'); childProcess = require('child_process');
if (mesh.hasKVM == 1) { obj.meshCoreCapabilities |= 1; } if (mesh.hasKVM == 1) { obj.meshCoreCapabilities |= 1; }
} else { } else {
// Running in nodejs // Running in nodejs
@ -91,22 +91,22 @@ function createMeshCore(agent) {
headers: { Host: "ipinfo.io" } headers: { Host: "ipinfo.io" }
}, },
function (resp) { function (resp) {
if (resp.statusCode == 200) { if (resp.statusCode == 200) {
var geoData = ''; var geoData = '';
resp.data = function (geoipdata) { geoData += geoipdata; }; resp.data = function (geoipdata) { geoData += geoipdata; };
resp.end = function () { resp.end = function () {
var location = null; var location = null;
try { try {
if (typeof geoData == 'string') { if (typeof geoData == 'string') {
var result = JSON.parse(geoData); var result = JSON.parse(geoData);
if (result.ip && result.loc) { location = result; } if (result.ip && result.loc) { location = result; }
} }
} catch (e) { } } catch (e) { }
if (func) { getIpLocationDataExCounts[1]++; func(location); } if (func) { getIpLocationDataExCounts[1]++; func(location); }
} }
} else { func(null); } } else { func(null); }
getIpLocationDataExInProgress = false; getIpLocationDataExInProgress = false;
}).end(); }).end();
return true; return true;
} }
catch (e) { return false; } catch (e) { return false; }
@ -311,6 +311,7 @@ function createMeshCore(agent) {
var xurl = getServerTargetUrlEx(data.value); var xurl = getServerTargetUrlEx(data.value);
if (xurl != null) { if (xurl != null) {
var woptions = http.parseUri(xurl); var woptions = http.parseUri(xurl);
woptions.rejectUnauthorized = 0;
sendConsoleText(JSON.stringify(woptions)); sendConsoleText(JSON.stringify(woptions));
var tunnel = http.request(woptions); var tunnel = http.request(woptions);
tunnel.upgrade = onTunnelUpgrade; tunnel.upgrade = onTunnelUpgrade;
@ -322,7 +323,8 @@ function createMeshCore(agent) {
tunnel.protocol = 0; tunnel.protocol = 0;
tunnel.tcpaddr = data.tcpaddr; tunnel.tcpaddr = data.tcpaddr;
tunnel.tcpport = data.tcpport; tunnel.tcpport = data.tcpport;
tunnel.end();
sendConsoleText('tunnel.end() called');
// Put the tunnel in the tunnels list // Put the tunnel in the tunnels list
var index = 1; var index = 1;
while (tunnels[index]) { index++; } while (tunnels[index]) { index++; }
@ -516,24 +518,26 @@ function createMeshCore(agent) {
if (obj.useNativePipes == false) { if (obj.useNativePipes == false) {
// Remote Terminal without using native pipes // Remote Terminal without using native pipes
if (process.platform == "win32") { if (process.platform == "win32") {
this.httprequest.terminal = processManager.CreateProcess("%windir%\\system32\\cmd.exe"); this.httprequest.terminal = childProcess.execFile("%windir%\\system32\\cmd.exe");
} else { } else {
this.httprequest.terminal = processManager.CreateProcess("/bin/sh", "sh", ILibProcessPipe_SpawnTypes.TERM); this.httprequest.terminal = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
} }
this.httprequest.terminal.tunnel = this; this.httprequest.terminal.tunnel = this;
this.httprequest.terminal.on('data', function (chunk) { this.tunnel.write(chunk); }); this.httprequest.terminal.on('exit', function (ecode, sig) { this.tunnel.end(); });
this.httprequest.terminal.error.data = function (chunk) { this.parent.tunnel.write(chunk); } this.httprequest.terminal.stdout.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
this.httprequest.terminal.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
} else { } else {
// Remote terminal using native pipes // Remote terminal using native pipes
if (process.platform == "win32") { if (process.platform == "win32") {
this.httprequest.process = processManager.CreateProcess("%windir%\\system32\\cmd.exe"); this.httprequest.process = childProcess.execFile("%windir%\\system32\\cmd.exe");
} else { } else {
this.httprequest.process = processManager.CreateProcess("/bin/sh", "sh", ILibProcessPipe_SpawnTypes.TERM); this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
} }
this.httprequest.process.tunnel = this; this.httprequest.process.tunnel = this;
this.httprequest.process.error.data = function (chunk) { this.parent.tunnel.write(chunk); } this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
this.httprequest.process.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
this.pipe(this.httprequest.process, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
} }
} }
if (this.httprequest.protocol == 2) { if (this.httprequest.protocol == 2) {
@ -810,7 +814,9 @@ function createMeshCore(agent) {
} else { } else {
var httprequest = null; var httprequest = null;
try { try {
httprequest = http.request(http.parseUri(args['_'][0])); var options = http.parseUri(args['_'][0]);
options.rejectUnauthorized = 0;
httprequest = http.request(options);
} catch (e) { response = 'Invalid HTTP websocket request'; } } catch (e) { response = 'Invalid HTTP websocket request'; }
if (httprequest != null) { if (httprequest != null) {
httprequest.upgrade = onWebSocketUpgrade; httprequest.upgrade = onWebSocketUpgrade;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2017 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral Intel AMT Event Parser * @description MeshCentral Intel(R) AMT Event Parser
* @author Ylian Saint-Hilaire & Bryan Roe * @author Ylian Saint-Hilaire & Bryan Roe
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral Intel AMT Local Scanner * @description MeshCentral Intel(R) AMT Local Scanner
* @author Ylian Saint-Hilaire & Joko Sastriawan * @author Ylian Saint-Hilaire & Joko Sastriawan
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @fileoverview Script Compiler / Decompiler / Runner * @fileoverview Script Compiler / Decompiler / Runner
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.1.0e * @version v0.1.0e
*/ */

View File

@ -1,8 +1,11 @@
/** /**
* @description Certificate generator * @description Certificate generator
* @author Joko Sastriawan / Ylian Saint-Hilaire * @author Joko Sastriawan / Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */
module.exports.CertificateOperations = function () { module.exports.CertificateOperations = function () {
var obj = {}; var obj = {};

View File

@ -1,4 +1,11 @@
 /**
* @description MeshCentral Common Library
* @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1
*/
var crypto = require('crypto'); var crypto = require('crypto');
// Binary encoding and decoding functions // Binary encoding and decoding functions

4
db.js
View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral database * @description MeshCentral database module
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.2 * @version v0.0.2
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Intel AMT Interceptor * @description MeshCentral Intel(R) AMT Interceptor
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.3 * @version v0.0.3
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral MeshAgent * @description MeshCentral MeshAgent communication module
* @author Ylian Saint-Hilaire & Bryan Roe * @author Ylian Saint-Hilaire & Bryan Roe
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral * @description MeshCentral main module
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral MeshMail * @description MeshCentral e-mail server communication modules
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */
@ -32,7 +34,14 @@ module.exports.CreateMeshMain = function (parent) {
// Perform all e-mail substitution // Perform all e-mail substitution
function mailReplacements(text, domain, username, email, cookie) { function mailReplacements(text, domain, username, email, cookie) {
var url = 'http' + ((obj.parent.args.notls == null) ? 's' : '') + '://' + parent.certificates.CommonName + ':' + obj.parent.args.port + domain.url; var url;
if (domain.dns == null) {
// Default domain or subdomain of the default.
url = 'http' + ((obj.parent.args.notls == null) ? 's' : '') + '://' + parent.certificates.CommonName + ':' + obj.parent.args.port + domain.url;
} else {
// Domain with a DNS name.
url = 'http' + ((obj.parent.args.notls == null) ? 's' : '') + '://' + domain.dns + ':' + obj.parent.args.port + domain.url;
}
if (cookie != null) { text = text.split('[[[CALLBACKURL]]]').join(url + 'checkmail?c=' + cookie) } if (cookie != null) { text = text.split('[[[CALLBACKURL]]]').join(url + 'checkmail?c=' + cookie) }
return text.split('[[[USERNAME]]]').join(username).split('[[[SERVERURL]]]').join(url).split('[[[SERVERNAME]]]').join(domain.title); return text.split('[[[USERNAME]]]').join(username).split('[[[SERVERURL]]]').join(url).split('[[[SERVERNAME]]]').join(domain.title);
} }

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral MeshRelay * @description MeshCentral connection relay module
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral Mesh Agent Local Scanner * @description MeshCentral Mesh Agent Local Scanner
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral MeshAgent * @description MeshCentral MeshAgent
* @author Ylian Saint-Hilaire & Bryan Roe * @author Ylian Saint-Hilaire & Bryan Roe
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral Intel AMT MPS server * @description MeshCentral Intel(R) AMT MPS server
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral Multi-Server Support * @description MeshCentral Multi-Server Support
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.1.1-r", "version": "0.1.1-u",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -2,6 +2,7 @@ MeshCentral
=========== ===========
For more information, [visit MeshCommander.com/MeshCentral2](http://www.meshcommander.com/meshcentral2). For more information, [visit MeshCommander.com/MeshCentral2](http://www.meshcommander.com/meshcentral2).
Download the [full PDF user's guide](http://info.meshcentral.com/downloads/meshcentral2/MeshCentral2UserGuide.pdf) with more information on installing, configuring and running MeshCentral2. Download the [full PDF user's guide](http://info.meshcentral.com/downloads/meshcentral2/MeshCentral2UserGuide.pdf) with more information on installing, configuring and running MeshCentral2.
This is a full computer management web site. With MeshCentral, you can run your own web server and it to remotely manage and control computers on a local network or anywhere on the internet. Once you get the server started, will create a mesh (a group of computers) and then download and install a mesh agent on each computer you want to manage. A minute later, the new computer will show up on the web site and you can take control of it, etc. MeshCentral includes full web-based remote desktop, terminal and file management capability. This is a full computer management web site. With MeshCentral, you can run your own web server and it to remotely manage and control computers on a local network or anywhere on the internet. Once you get the server started, will create a mesh (a group of computers) and then download and install a mesh agent on each computer you want to manage. A minute later, the new computer will show up on the web site and you can take control of it, etc. MeshCentral includes full web-based remote desktop, terminal and file management capability.

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral web server * @description Meshcentral web server
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral1 legacy swarm server, used to update agents and get them on MeshCentral2 * @description MeshCentral v1 legacy Swarm Server, used to update agents and get them on MeshCentral2
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */

View File

@ -1,6 +1,8 @@
/** /**
* @description Meshcentral web server * @description MeshCentral web server
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018
* @license Apache-2.0
* @version v0.0.1 * @version v0.0.1
*/ */
@ -126,8 +128,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
{ {
var dnscount = 0; var dnscount = 0;
obj.tlsSniCredentials = {}; obj.tlsSniCredentials = {};
for (var i in obj.certificates.dns) { if (obj.parent.config.domains[i].dns != null) { obj.dnsDomains[obj.parent.config.domains[i].dns.toLowerCase()] = obj.parent.config.domains[i]; obj.tlsSniCredentials[obj.parent.config.domains[i].dns] = obj.crypto.createCredentials(obj.certificates.dns[i]).context; dnscount++; } } for (var i in obj.certificates.dns) { if (obj.parent.config.domains[i].dns != null) { obj.dnsDomains[obj.parent.config.domains[i].dns.toLowerCase()] = obj.parent.config.domains[i]; obj.tlsSniCredentials[obj.parent.config.domains[i].dns] = obj.tls.createSecureContext(obj.certificates.dns[i]).context; dnscount++; } }
if (dnscount > 0) { obj.tlsSniCredentials[''] = obj.crypto.createCredentials({ cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.ca }).context; } else { obj.tlsSniCredentials = null; } if (dnscount > 0) { obj.tlsSniCredentials[''] = obj.tls.createSecureContext({ cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.ca }).context; } else { obj.tlsSniCredentials = null; }
} }
function TlsSniCallback(name, cb) { var c = obj.tlsSniCredentials[name]; if (c != null) { cb(null, c); } else { cb(null, obj.tlsSniCredentials['']); } } function TlsSniCallback(name, cb) { var c = obj.tlsSniCredentials[name]; if (c != null) { cb(null, c); } else { cb(null, obj.tlsSniCredentials['']); } }
@ -1535,6 +1537,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
obj.app.post('/restoreserver.ashx', handleRestoreRequest); obj.app.post('/restoreserver.ashx', handleRestoreRequest);
if (parent.multiServer != null) { obj.app.ws('/meshserver.ashx', function (ws, req) { parent.multiServer.CreatePeerInServer(parent.multiServer, ws, req); } ); } if (parent.multiServer != null) { obj.app.ws('/meshserver.ashx', function (ws, req) { parent.multiServer.CreatePeerInServer(parent.multiServer, ws, req); } ); }
for (var i in parent.config.domains) { for (var i in parent.config.domains) {
if (parent.config.domains[i].dns != null) { continue; } // This is a subdomain with a DNS name, no added HTTP bindings needed.
var url = parent.config.domains[i].url; var url = parent.config.domains[i].url;
obj.app.get(url, handleRootRequest); obj.app.get(url, handleRootRequest);
obj.app.get(url + 'terms', handleTermsRequest); obj.app.get(url + 'terms', handleTermsRequest);