Fixed FIDO2, added alt RDP port, fixed device tag collapse.

Ylian Saint-Hilaire committed Jan 27, 2020 at 14:03 UTC 1f658fb393bd65d8408b82c21c8c5a1c6a19e5b7
5 files changed +41 -20
meshcentral.js
+1
@@ -1894,6 +1894,7 @@ function CreateMeshCentralServer(config, args) {
1894 hashStream.archid = archid;
1895 hashStream.on('data', function (data) {
1896 obj.meshAgentBinaries[this.archid].hash = data.toString('binary');
1897 + obj.meshAgentBinaries[this.archid].hashhex = data.toString('hex');
1898 if ((--archcount == 0) && (func != null)) { func(); }
1899 });
1900 var options = { sourcePath: agentpath, targetStream: hashStream, platform: obj.meshAgentsArchitectureNumbers[archid].platform };
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.4.7-y",
3 + "version": "0.4.7-z",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/default.handlebars
+37 -17
@@ -65,6 +65,9 @@
65 <div id="cxtermnorm" class="cmtext" onclick="cmtermaction(1,event)"><b>Root Shell</b></div>
66 <div id="cxtermps" class="cmtext" onclick="cmtermaction(8,event)">User Shell</div>
67 </div>
68 + <div id="altPortContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
69 + <div id="cxaltport" class="cmtext" onclick="cmaltportaction(1,event)"><b>Alternate Port</b></div>
70 + </div>
71 <!--
72 <div id="pluginTabContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
73 <div id="cxclose" class="cmtext" onclick="pluginTabClose(event)">Close Tab</div>
@@ -2153,16 +2156,18 @@
2156 var publicKey = message.request;
2157 message.request.challenge = Uint8Array.from(atob(message.request.challenge), function (c) { return c.charCodeAt(0) })
2158 message.request.user.id = Uint8Array.from(atob(message.request.user.id), function (c) { return c.charCodeAt(0) })
2156 - navigator.credentials.create({ publicKey: publicKey })
2157 - .then(function(newCredentialInfo) {
2158 - // Public key credential
2159 - var r = { rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.rawId))), response: { attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.clientDataJSON))) }, type: newCredentialInfo.type };
2160 - meshserver.send({ action: 'webauthn-endregister', response: r });
2161 - setDialogMode(0);
2162 - }, function(error) {
2163 - // Error
2164 - setDialogMode(2, "Add Security Key", 1, null, "ERROR: " + error);
2165 - });
2159 + setTimeout(function() {
2160 + navigator.credentials.create({ publicKey: publicKey })
2161 + .then(function(newCredentialInfo) {
2162 + // Public key credential
2163 + var r = { rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.rawId))), response: { attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.clientDataJSON))) }, type: newCredentialInfo.type };
2164 + meshserver.send({ action: 'webauthn-endregister', response: r });
2165 + setDialogMode(0);
2166 + }, function(error) {
2167 + // Error
2168 + setDialogMode(2, "Add Security Key", 1, null, "ERROR: " + error);
2169 + });
2170 + }, 100);
2171 break;
2172 }
2173 case 'event': {
@@ -3051,13 +3056,13 @@
3056 var i = groupNames[j];
3057 if (view == 2) {
3058 r += '<tr><td colspan=4><div class=DevSt style=width:100%;padding-top:4px>';
3054 - var collapsed = CollapsedGroups['tag:' + i];
3055 - r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + i + '\",2)></img>'; // Collapse action
3059 + var collapsed = CollapsedGroups['tag:' + encodeURIComponent(i)];
3060 + r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + encodeURIComponent(i) + '\",2)></img>'; // Collapse action
3061 r += '<span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span><span>' + i + '</span></div>' + groups[i];
3062 } else {
3063 r += '<div class=DevSt style=width:100%;padding-top:4px><span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span>';
3059 - var collapsed = CollapsedGroups['tag:' + i];
3060 - r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + i + '\")></img>'; // Collapse action
3064 + var collapsed = CollapsedGroups['tag:' + encodeURIComponent(i)];
3065 + r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + encodeURIComponent(i) + '\")></img>'; // Collapse action
3066 r += '<span>' + i + '</span></div>';
3067 r += '<div id=DevxCol' + tagDeviceHeaderId + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
3068 r += groups[i];
@@ -3895,7 +3900,12 @@
3900 var scrollLeft = (window.pageXOffset !== null) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
3901 var scrollTop = (window.pageYOffset !== null) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
3902 var elem = document.elementFromPoint(event.pageX - scrollLeft, event.pageY - scrollTop);
3898 - if (elem && elem != null && elem.id == 'connectbutton2' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3903 +
3904 + if (elem && elem != null && elem.id == 'rdpClickOnceLink' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3905 + contextelement = elem;
3906 + var contextmenudiv = document.getElementById('altPortContextMenu');
3907 + showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
3908 + } else if (elem && elem != null && elem.id == 'connectbutton2' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3909 contextelement = elem;
3910 var contextmenudiv = document.getElementById('termShellContextMenu');
3911 showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
@@ -3936,7 +3946,6 @@
3946 QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8));
3947 QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8));
3948 }
3939 -
3949 return haltEvent(event);
3950 }
3951
@@ -3990,6 +3999,16 @@
3999 connectTerminal(null, 1, { protocol: action });
4000 }
4001
4002 + function cmaltportaction(action) {
4003 + if (xxdialogMode) return;
4004 + var x = "RDP remote connection port:" + '<br /><br /><input type=text placeholder="3389" inputmode="numeric" pattern="[0-9]*" onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" maxlength=5 id=d10rdpport type=text>';
4005 + setDialogMode(2, "RDP Connection", 3, function() {
4006 + setDialogMode(0);
4007 + if (currentNode != null) { p10clickOnce(currentNode._id, "RDP2", ((Q('d10rdpport').value.length > 0) ? parseInt(Q('d10rdpport').value) : 3389)); }
4008 + }, x, currentNode);
4009 + Q('d10rdpport').focus();
4010 + }
4011 +
4012 /*
4013 function pluginTabClose() {
4014 var pluginTab = contextelement;
@@ -4007,6 +4026,7 @@
4026 QV('meshContextMenu', false);
4027 QV('termShellContextMenu', false);
4028 QV('termShellContextMenuLinux', false);
4029 + QV('altPortContextMenu', false);
4030 //QV('pluginTabContextMenu', false);
4031 contextelement = null;
4032 }
@@ -4828,7 +4848,7 @@
4848
4849 // RDP link, show this link only of the remote machine is Windows.
4850 if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
4831 - if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# onclick=p10clickOnce("' + node._id + '","RDP2",3389) title=\"' + "Requires Microsoft ClickOnce support in your browser" + '.\">' + "RDP" + '</a>&nbsp;'; }
4851 + if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# id=rdpClickOnceLink onclick=p10clickOnce("' + node._id + '","RDP2",3389) title=\"' + "Requires Microsoft ClickOnce support in your browser" + '.\">' + "RDP" + '</a>&nbsp;'; }
4852 if (node.agent.id > 4) {
4853 x += '<a href=# onclick=p10clickOnce("' + node._id + '","PSSH",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "Putty" + '</a>&nbsp;';
4854 x += '<a href=# onclick=p10clickOnce("' + node._id + '","WSCP",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "WinSCP" + '</a>&nbsp;';
webauthn.js
+1 -1
@@ -35,7 +35,7 @@ module.exports.CreateWebAuthnModule = function () {
35
36 const response = { 'verified': false };
37
38 - if (ctapMakeCredResp.fmt === 'none') {
38 + if ((ctapMakeCredResp.fmt === 'none') || (ctapMakeCredResp.fmt === 'fido-u2f')) {
39 if (!(authrDataStruct.flags & 0x01)) { throw new Error('User was NOT presented during authentication!'); } // U2F_USER_PRESENTED
40
41 const publicKey = COSEECDHAtoPKCS(authrDataStruct.COSEPublicKey);
webserver.js
+1 -1
@@ -3177,7 +3177,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3177 var agentinfo = obj.parent.meshAgentBinaries[agentid];
3178 response += '<tr><td>' + agentinfo.id + '</td><td>' + agentinfo.desc + '</td>';
3179 response += '<td><a download href="' + req.originalUrl + '?id=' + agentinfo.id + '">' + agentinfo.rname + '</a></td>';
3180 - response += '<td>' + agentinfo.size + '</td><td>' + agentinfo.hash + '</td>';
3180 + response += '<td>' + agentinfo.size + '</td><td>' + agentinfo.hashhex + '</td>';
3181 response += '<td><a download href="' + req.originalUrl + '?meshcmd=' + agentinfo.id + '">' + agentinfo.rname.replace('agent', 'cmd') + '</a></td></tr>';
3182 }
3183 response += '</table></body></html>';