mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-09-11 08:55:32 +03:00
Allows MeshCommander to relay thru MeshCentral.
This commit is contained in:
parent
207bad322a
commit
564646fcdf
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.2.2-d",
|
"version": "0.2.2-e",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
<td id=devListToolbar class=style14>
|
<td id=devListToolbar class=style14>
|
||||||
<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />
|
<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />
|
||||||
<input type=button id=GroupActionButton disabled="disabled" value="Group Action" onclick=groupActionFunction() />
|
<input type=button id=GroupActionButton disabled="disabled" value="Group Action" onclick=groupActionFunction() />
|
||||||
<input id=SearchInput type=text style=width:120px placeholder=Search onchange=onSearchInputChanged() onkeyup=onSearchInputChanged() autocomplete=off onfocus=onSearchFocus(1) onblur=onSearchFocus(0) />
|
<input id=SearchInput type=text style=width:120px placeholder=Filter onchange=onSearchInputChanged() onkeyup=onSearchInputChanged() autocomplete=off onfocus=onSearchFocus(1) onblur=onSearchFocus(0) />
|
||||||
<input type=checkbox id=RealNameCheckBox onclick=onRealNameCheckBox() /><span title="Show devices operating system name">OS Name</span>
|
<input type=checkbox id=RealNameCheckBox onclick=onRealNameCheckBox() /><span title="Show devices operating system name">OS Name</span>
|
||||||
</td>
|
</td>
|
||||||
<td id=kvmListToolbar class=style14 style=height:100%>
|
<td id=kvmListToolbar class=style14 style=height:100%>
|
||||||
@ -281,7 +281,7 @@
|
|||||||
<td class=style14>
|
<td class=style14>
|
||||||
|
|
||||||
<input type=button onclick=showCreateNewAccountDialog() value="New Account..." />
|
<input type=button onclick=showCreateNewAccountDialog() value="New Account..." />
|
||||||
<input id=UserSearchInput type=text style=width:120px placeholder=Search onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) />
|
<input id=UserSearchInput type=text style=width:120px placeholder=Filter onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) />
|
||||||
</td>
|
</td>
|
||||||
<td class=h2></td>
|
<td class=h2></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
110
webserver.js
110
webserver.js
@ -1081,8 +1081,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (!user) { console.log('ERR: Not a user'); return; }
|
if (!user) { console.log('ERR: Not a user'); return; }
|
||||||
Debug(1, 'Websocket relay connected from ' + user.name + ' for ' + req.query.host + '.');
|
Debug(1, 'Websocket relay connected from ' + user.name + ' for ' + req.query.host + '.');
|
||||||
|
|
||||||
ws.pause(); // Hold this socket until we are ready.
|
ws.pause(); // Hold this socket until we are ready.
|
||||||
ws._socket.setKeepAlive(true, 240000); // Set TCP keep alive
|
try { ws._socket.setKeepAlive(true, 240000); } catch (ex) { } // Set TCP keep alive
|
||||||
|
|
||||||
// Fetch information about the target
|
// Fetch information about the target
|
||||||
obj.db.Get(req.query.host, function (err, docs) {
|
obj.db.Get(req.query.host, function (err, docs) {
|
||||||
@ -1150,7 +1150,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (data.length > 0) { try { ser.updateBuffer(Buffer.from(data, 'binary')); } catch (e) { } }
|
if (data.length > 0) { try { ser.updateBuffer(Buffer.from(data, 'binary')); } catch (e) { } }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handke CIRA tunnel state change
|
// Handle CIRA tunnel state change
|
||||||
chnl.onStateChange = function (ciraconn, state) {
|
chnl.onStateChange = function (ciraconn, state) {
|
||||||
Debug(2, 'Relay TLS CIRA state change', state);
|
Debug(2, 'Relay TLS CIRA state change', state);
|
||||||
if (state == 0) { try { ws.close(); } catch (e) { } }
|
if (state == 0) { try { ws.close(); } catch (e) { } }
|
||||||
@ -1169,6 +1169,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
try {
|
try {
|
||||||
data = data.toString('binary');
|
data = data.toString('binary');
|
||||||
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
||||||
|
//ws.send(Buffer.from(data, 'binary'));
|
||||||
ws.send(data);
|
ws.send(data);
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
});
|
});
|
||||||
@ -1209,7 +1210,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
ws.forwardclient.onData = function (ciraconn, data) {
|
ws.forwardclient.onData = function (ciraconn, data) {
|
||||||
Debug(4, 'Relay CIRA data', data.length);
|
Debug(4, 'Relay CIRA data', data.length);
|
||||||
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
||||||
if (data.length > 0) { try { ws.send(data); } catch (e) { } } // TODO: Add TLS support
|
if (data.length > 0) { try { ws.send(new Buffer(data, 'binary')); } catch (e) { } } // TODO: Add TLS support
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.forwardclient.onSendOk = function (ciraconn) {
|
ws.forwardclient.onSendOk = function (ciraconn) {
|
||||||
@ -1801,8 +1802,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
obj.app.post(url + 'resetaccount', handleResetAccountRequest);
|
obj.app.post(url + 'resetaccount', handleResetAccountRequest);
|
||||||
obj.app.get(url + 'checkmail', handleCheckMailRequest);
|
obj.app.get(url + 'checkmail', handleCheckMailRequest);
|
||||||
obj.app.post(url + 'amtevents.ashx', obj.handleAmtEventRequest);
|
obj.app.post(url + 'amtevents.ashx', obj.handleAmtEventRequest);
|
||||||
obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
|
|
||||||
obj.app.ws(url + 'webrelay.ashx', handleRelayWebSocket);
|
|
||||||
obj.app.get(url + 'meshagents', obj.handleMeshAgentRequest);
|
obj.app.get(url + 'meshagents', obj.handleMeshAgentRequest);
|
||||||
obj.app.get(url + 'meshosxagent', obj.handleMeshOsxAgentRequest);
|
obj.app.get(url + 'meshosxagent', obj.handleMeshOsxAgentRequest);
|
||||||
obj.app.get(url + 'meshsettings', obj.handleMeshSettingsRequest);
|
obj.app.get(url + 'meshsettings', obj.handleMeshSettingsRequest);
|
||||||
@ -1812,57 +1811,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
obj.app.get(url + 'userfiles/*', handleDownloadUserFiles);
|
obj.app.get(url + 'userfiles/*', handleDownloadUserFiles);
|
||||||
obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
|
obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
|
||||||
obj.app.ws(url + 'meshrelay.ashx', function (ws, req) { try { obj.meshRelayHandler.CreateMeshRelay(obj, ws, req, getDomain(req)); } catch (e) { console.log(e); } });
|
obj.app.ws(url + 'meshrelay.ashx', function (ws, req) { try { obj.meshRelayHandler.CreateMeshRelay(obj, ws, req, getDomain(req)); } catch (e) { console.log(e); } });
|
||||||
|
obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
|
||||||
// User login
|
obj.app.ws(url + 'webrelay.ashx', function (ws, req) { PerformSessionAuth(ws, req, handleRelayWebSocket); });
|
||||||
obj.app.ws(url + 'control.ashx', function (ws, req) {
|
obj.app.ws(url + 'control.ashx', function (ws, req) { PerformSessionAuth(ws, req, function (ws1, req1, domain) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain); }); });
|
||||||
try {
|
|
||||||
var domain = checkUserIpAddress(ws, req);
|
|
||||||
if (domain != null) {
|
|
||||||
var loginok = false;
|
|
||||||
// Check if the user is logged in
|
|
||||||
if ((!req.session) || (!req.session.userid) || (req.session.domainid != domain.id)) {
|
|
||||||
// If a default user is active, setup the session here.
|
|
||||||
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
|
|
||||||
if (req.session && req.session.loginmode) { delete req.session.loginmode; }
|
|
||||||
req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase();
|
|
||||||
req.session.domainid = domain.id;
|
|
||||||
req.session.currentNode = '';
|
|
||||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
|
||||||
loginok = true;
|
|
||||||
} else {
|
|
||||||
// See the the user/pass is provided in URL arguments
|
|
||||||
if ((req.query.user != null) && (req.query.pass != null)) {
|
|
||||||
loginok = true;
|
|
||||||
obj.authenticate(req.query.user, req.query.pass, domain, function (err, userid) {
|
|
||||||
var loginok2 = false;
|
|
||||||
if (err == null) {
|
|
||||||
var user = obj.users[userid];
|
|
||||||
if (user) {
|
|
||||||
req.session.userid = userid;
|
|
||||||
req.session.domainid = domain.id;
|
|
||||||
req.session.currentNode = '';
|
|
||||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
|
||||||
loginok2 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (loginok2 == false) {
|
|
||||||
// Close the websocket connection
|
|
||||||
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
|
||||||
loginok = true;
|
|
||||||
}
|
|
||||||
if (loginok == false) {
|
|
||||||
// Close the websocket connection
|
|
||||||
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) { console.log(e); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// Server picture
|
// Server picture
|
||||||
obj.app.get(url + 'serverpic.ashx', function (req, res) {
|
obj.app.get(url + 'serverpic.ashx', function (req, res) {
|
||||||
@ -1895,6 +1846,51 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
obj.app.use(url, obj.express.static(obj.path.join(__dirname, 'public')));
|
obj.app.use(url, obj.express.static(obj.path.join(__dirname, 'public')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Authenticates a session and forwards
|
||||||
|
function PerformSessionAuth(ws, req, func) {
|
||||||
|
try {
|
||||||
|
var domain = checkUserIpAddress(ws, req);
|
||||||
|
if (domain != null) {
|
||||||
|
var loginok = false;
|
||||||
|
// Check if the user is logged in
|
||||||
|
if ((!req.session) || (!req.session.userid) || (req.session.domainid != domain.id)) {
|
||||||
|
// If a default user is active, setup the session here.
|
||||||
|
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
|
||||||
|
if (req.session && req.session.loginmode) { delete req.session.loginmode; }
|
||||||
|
req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase();
|
||||||
|
req.session.domainid = domain.id;
|
||||||
|
func(ws, req, domain);
|
||||||
|
loginok = true;
|
||||||
|
} else {
|
||||||
|
// See the the user/pass is provided in URL arguments
|
||||||
|
if ((req.query.user != null) && (req.query.pass != null)) {
|
||||||
|
loginok = true;
|
||||||
|
obj.authenticate(req.query.user, req.query.pass, domain, function (err, userid) {
|
||||||
|
var loginok2 = false;
|
||||||
|
if (err == null) {
|
||||||
|
var user = obj.users[userid];
|
||||||
|
if (user) {
|
||||||
|
req.session.userid = userid;
|
||||||
|
req.session.domainid = domain.id;
|
||||||
|
func(ws, req, domain);
|
||||||
|
loginok2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If not authenticated, close the websocket connection
|
||||||
|
if (loginok2 == false) { try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { } }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
func(ws, req, domain);
|
||||||
|
loginok = true;
|
||||||
|
}
|
||||||
|
// If not authenticated, close the websocket connection
|
||||||
|
if (loginok == false) { try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { } }
|
||||||
|
}
|
||||||
|
} catch (e) { console.log(e); }
|
||||||
|
}
|
||||||
|
|
||||||
// Find a free port starting with the specified one and going up.
|
// Find a free port starting with the specified one and going up.
|
||||||
function CheckListenPort(port, func) {
|
function CheckListenPort(port, func) {
|
||||||
var s = obj.net.createServer(function (socket) { });
|
var s = obj.net.createServer(function (socket) { });
|
||||||
|
Loading…
Reference in New Issue
Block a user