diff --git a/agents/meshcore.js b/agents/meshcore.js index c5e65f8a..28d45d4d 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -776,7 +776,12 @@ function createMeshCore(agent) { var woptions = http.parseUri(xurl); woptions.perMessageDeflate = false; if (typeof data.perMessageDeflate == 'boolean') { woptions.perMessageDeflate = data.perMessageDeflate; } + + // Perform manual server TLS certificate checking based on the certificate hash given by the server. woptions.rejectUnauthorized = 0; + woptions.checkServerIdentity = function checkServerIdentity(certs) { if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash != certs[0].fingerprint.split(':').join('').toLowerCase())) { throw new Error('BadCert') } } + woptions.checkServerIdentity.servertlshash = data.servertlshash; + //sendConsoleText(JSON.stringify(woptions)); //sendConsoleText('TUNNEL: ' + JSON.stringify(data)); var tunnel = http.request(woptions); @@ -1147,7 +1152,12 @@ function createMeshCore(agent) { data.url = 'http' + getServerTargetUrlEx('*/').substring(2); var agentFileHttpOptions = http.parseUri(data.url); agentFileHttpOptions.path = data.urlpath; - agentFileHttpOptions.rejectUnauthorized = 0; // TODO: Check TLS cert + + // Perform manual server TLS certificate checking based on the certificate hash given by the server. + agentFileHttpOptions.rejectUnauthorized = 0; + agentFileHttpOptions.checkServerIdentity = function checkServerIdentity(certs) { if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash != certs[0].fingerprint.split(':').join('').toLowerCase())) { throw new Error('BadCert') } } + agentFileHttpOptions.checkServerIdentity.servertlshash = data.servertlshash; + if (agentFileHttpOptions == null) break; var agentFileHttpRequest = http.request(agentFileHttpOptions, function (response) { diff --git a/meshuser.js b/meshuser.js index a9be1a26..d2060db9 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1328,6 +1328,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (url.query.p == '1') { requiredNonRights = MESHRIGHT_NOTERMINAL; } else if ((url.query.p == '4') || (url.query.p == '5')) { requiredNonRights = MESHRIGHT_NOFILES; } + // Add server TLS cert hash + const tlsCertHash = parent.webCertificateHashs[domain.id]; + if (tlsCertHash != null) { command.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); } + // Add user consent messages command.soptions = {}; if (typeof domain.consentmessages == 'object') { diff --git a/webserver.js b/webserver.js index b376d904..129288f3 100644 --- a/webserver.js +++ b/webserver.js @@ -3223,12 +3223,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Instruct one of more agents to download a URL to a given local drive location. function handleUploadFileBatchEx(cmd) { + var tlsCertHash = obj.webCertificateHashs[cmd.domain.id]; + if (tlsCertHash != null) { tlsCertHash = Buffer.from(tlsCertHash, 'binary').toString('hex'); } for (var i in cmd.nodeids) { obj.GetNodeWithRights(cmd.domain, cmd.user, cmd.nodeids[i], function (node, rights, visible) { if ((node == null) || ((rights & 8) == 0) || (visible == false)) return; // We don't have remote control rights to this device var agentPath = ((node.agent.id > 0) && (node.agent.id < 5)) ? cmd.windowsPath : cmd.linuxPath; for (var f in cmd.files) { - const acmd = { action: 'wget', overwrite: cmd.overwrite, urlpath: '/agentdownload.ashx?c=' + obj.parent.encodeCookie({ a: 'tmpdl', d: cmd.domain.id, nid: node._id, f: cmd.files[f].target }, obj.parent.loginCookieEncryptionKey), path: obj.path.join(agentPath, cmd.files[f].name) }; + const acmd = { action: 'wget', overwrite: cmd.overwrite, urlpath: '/agentdownload.ashx?c=' + obj.parent.encodeCookie({ a: 'tmpdl', d: cmd.domain.id, nid: node._id, f: cmd.files[f].target }, obj.parent.loginCookieEncryptionKey), path: obj.path.join(agentPath, cmd.files[f].name), servertlshash: tlsCertHash }; var agent = obj.wsagents[node._id]; if (agent != null) { try { agent.send(JSON.stringify(acmd)); } catch (ex) { } } // TODO: Add support for peer servers.