mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Started work on IP-KVM relay code.
This commit is contained in:
		
							parent
							
								
									448aeec6e7
								
							
						
					
					
						commit
						61e38cbe36
					
				
					 2 changed files with 65 additions and 12 deletions
				
			
		
							
								
								
									
										24
									
								
								meshipkvm.js
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								meshipkvm.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
 | 
			
		||||
function CreateIPKVMManager(parent) {
 | 
			
		||||
    const obj = {};
 | 
			
		||||
    const managedGroups = {} // meshid --> Manager
 | 
			
		||||
    obj.managedGroups = {} // meshid --> Manager
 | 
			
		||||
    obj.managedPorts = {} // nodeid --> PortInfo
 | 
			
		||||
    
 | 
			
		||||
    // Subscribe for mesh creation events
 | 
			
		||||
| 
						 | 
				
			
			@ -31,14 +31,14 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
    
 | 
			
		||||
    // Start managing a IP KVM device
 | 
			
		||||
    function startManagement(mesh) {
 | 
			
		||||
        if ((mesh == null) || (mesh.mtype != 4) || (mesh.kvm == null) || (mesh.deleted != null) || (managedGroups[mesh._id] != null)) return;
 | 
			
		||||
        if ((mesh == null) || (mesh.mtype != 4) || (mesh.kvm == null) || (mesh.deleted != null) || (obj.managedGroups[mesh._id] != null)) return;
 | 
			
		||||
        var port = 443, hostSplit = mesh.kvm.host.split(':'), host = hostSplit[0];
 | 
			
		||||
        if (hostSplit.length == 2) { port = parseInt(hostSplit[1]); }
 | 
			
		||||
        if (mesh.kvm.model == 1) { // Raritan KX III
 | 
			
		||||
            const manager = CreateRaritanKX3Manager(host, port, mesh.kvm.user, mesh.kvm.pass);
 | 
			
		||||
            manager.meshid = mesh._id;
 | 
			
		||||
            manager.domainid = mesh._id.split('/')[1];
 | 
			
		||||
            managedGroups[mesh._id] = manager;
 | 
			
		||||
            obj.managedGroups[mesh._id] = manager;
 | 
			
		||||
            manager.onStateChanged = onStateChanged;
 | 
			
		||||
            manager.onPortsChanged = onPortsChanged;
 | 
			
		||||
            manager.start();
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
    
 | 
			
		||||
    // Stop managing a IP KVM device
 | 
			
		||||
    function stopManagement(meshid) {
 | 
			
		||||
        const manager = managedGroups[meshid];
 | 
			
		||||
        const manager = obj.managedGroups[meshid];
 | 
			
		||||
        if (manager != null) {
 | 
			
		||||
            // Remove all managed ports
 | 
			
		||||
            for (var i = 0; i < manager.ports.length; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            // Remove the manager
 | 
			
		||||
            delete managedGroups[meshid];
 | 
			
		||||
            delete obj.managedGroups[meshid];
 | 
			
		||||
            manager.stop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
                        // Set the connectivity state if needed
 | 
			
		||||
                        if (obj.managedPorts[nodeid] == null) {
 | 
			
		||||
                            parent.SetConnectivityState(sender.meshid, nodeid, Date.now(), 1, 1, null, null);
 | 
			
		||||
                            obj.managedPorts[nodeid] = { name: port.Name };
 | 
			
		||||
                            obj.managedPorts[nodeid] = { name: port.Name, meshid: sender.meshid, portid: port.PortId };
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Update busy state
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +265,7 @@ function CreateRaritanKX3Manager(hostname, port, username, password) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    function fetchInitialInformation() {
 | 
			
		||||
        fetch('/webs_cron.asp?_portsstatushash=&_devicesstatushash=&webs_job=sidebarupdates', null, null, function (server, tag, data) {
 | 
			
		||||
        obj.fetch('/webs_cron.asp?_portsstatushash=&_devicesstatushash=&webs_job=sidebarupdates', null, null, function (server, tag, data) {
 | 
			
		||||
            const parsed = parseJsScript(data);
 | 
			
		||||
            for (var i in parsed['updateSidebarPanel']) {
 | 
			
		||||
                if (parsed['updateSidebarPanel'][i][0] == "cron_device") {
 | 
			
		||||
| 
						 | 
				
			
			@ -273,7 +273,7 @@ function CreateRaritanKX3Manager(hostname, port, username, password) {
 | 
			
		|||
                    obj.deviceModel = getSubString(parsed['updateSidebarPanel'][i][1], "<div class=\"device-model\">", "<");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            fetch('/sidebar.asp', null, null, function (server, tag, data) {
 | 
			
		||||
            obj.fetch('/sidebar.asp', null, null, function (server, tag, data) {
 | 
			
		||||
                var dataBlock = getSubString(data, "updateKVMLinkHintOnContainer();", "devices.resetDevicesNew(1);");
 | 
			
		||||
                if (dataBlock == null) { setState(0); return; }
 | 
			
		||||
                const parsed = parseJsScript(dataBlock);
 | 
			
		||||
| 
						 | 
				
			
			@ -294,7 +294,7 @@ function CreateRaritanKX3Manager(hostname, port, username, password) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    obj.update = function () {
 | 
			
		||||
        fetch('/webs_cron.asp?_portsstatushash=' + obj.portHash + '&_devicesstatushash=' + obj.deviceHash, null, null, function (server, tag, data) {
 | 
			
		||||
        obj.fetch('/webs_cron.asp?_portsstatushash=' + obj.portHash + '&_devicesstatushash=' + obj.deviceHash, null, null, function (server, tag, data) {
 | 
			
		||||
            const parsed = parseJsScript(data);
 | 
			
		||||
            if (parsed['updatePortStatus']) {
 | 
			
		||||
                obj.portCount = parseInt(parsed['updatePortStatus'][0][0]) - 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +396,7 @@ function CreateRaritanKX3Manager(hostname, port, username, password) {
 | 
			
		|||
        return ((char >= 'A') && (char <= 'Z')) || ((char >= 'a') && (char <= 'z')) || ((char >= '0') && (char <= '9'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function fetch(url, postdata, tag, func) {
 | 
			
		||||
    obj.fetch = function(url, postdata, tag, func) {
 | 
			
		||||
        if (obj.state == 0) return;
 | 
			
		||||
        var data = '';
 | 
			
		||||
        const options = {
 | 
			
		||||
| 
						 | 
				
			
			@ -416,9 +416,9 @@ function CreateRaritanKX3Manager(hostname, port, username, password) {
 | 
			
		|||
            if (res.statusCode != 200) { setState(0); return; }
 | 
			
		||||
            if (res.headers['set-cookie'] != null) { for (var i in res.headers['set-cookie']) { if (res.headers['set-cookie'][i].startsWith('pp_session_id=')) { obj.authCookie = res.headers['set-cookie'][i].substring(14).split(';')[0]; } } }
 | 
			
		||||
            res.on('data', function (d) { data += d; });
 | 
			
		||||
            res.on('end', function () { func(obj, tag, data); });
 | 
			
		||||
            res.on('end', function () { func(obj, tag, data, res); });
 | 
			
		||||
        });
 | 
			
		||||
        req.on('error', function (error) { setState(0); })
 | 
			
		||||
        req.on('error', function (error) { console.log(error); setState(0); })
 | 
			
		||||
        req.end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5848,6 +5848,59 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
                obj.app.get(url + 'pluginHandler.js', obj.handlePluginJS);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Setup IP-KVM relay if supported
 | 
			
		||||
            if (domain.ipkvm) {
 | 
			
		||||
                obj.app.ws(url + 'ipkvm.ashx/*', function (ws, req) {
 | 
			
		||||
                    const domain = getDomain(req);
 | 
			
		||||
                    if (domain == null) { parent.debug('web', 'ipkvm: failed domain checks.'); try { ws.close(); } catch (ex) { } return; }
 | 
			
		||||
                    const q = require('url').parse(req.url, true);
 | 
			
		||||
                    const i = q.path.indexOf('/ipkvm.ashx/');
 | 
			
		||||
                    if (i == -1) { parent.debug('web', 'ipkvm: failed url checks.'); try { ws.close(); } catch (ex) { } return; }
 | 
			
		||||
                    const urlargs = q.path.substring(i + 12).split('/');
 | 
			
		||||
                    if (urlargs[0].length != 64) { parent.debug('web', 'ipkvm: failed nodeid length checks.'); try { ws.close(); } catch (ex) { } return; }
 | 
			
		||||
                    const nodeid = 'node/' + domain.id + '/' + urlargs[0];
 | 
			
		||||
                    const nid = urlargs[0];
 | 
			
		||||
                    const kvmport = parent.ipKvmManager.managedPorts[nodeid];
 | 
			
		||||
                    if (kvmport == null) { parent.debug('web', 'ipkvm: failed port checks.'); try { ws.close(); } catch (ex) { } return; }
 | 
			
		||||
                    const kvmmanager = parent.ipKvmManager.managedGroups[kvmport.meshid];
 | 
			
		||||
                    if (kvmmanager == null) { parent.debug('web', 'ipkvm: failed manager checks.'); try { ws.close(); } catch (ex) { } return; }
 | 
			
		||||
                    urlargs.shift();
 | 
			
		||||
                    var relurl = '/' + urlargs.join('/')
 | 
			
		||||
                    if (relurl.endsWith('/.websocket')) { relurl = relurl.substring(0, relurl.length - 11); }
 | 
			
		||||
                    console.log('ws', relurl); // TODO
 | 
			
		||||
                });
 | 
			
		||||
                obj.app.get(url + 'ipkvm.ashx/*', function (req, res, next) {
 | 
			
		||||
                    const domain = getDomain(req);
 | 
			
		||||
                    if (domain == null) { return; }
 | 
			
		||||
                    const q = require('url').parse(req.url, true);
 | 
			
		||||
                    const i = q.path.indexOf('/ipkvm.ashx/');
 | 
			
		||||
                    if (i == -1) { next(); return; }
 | 
			
		||||
                    const urlargs = q.path.substring(i + 12).split('/');
 | 
			
		||||
                    if (urlargs[0].length != 64) { next(); return; }
 | 
			
		||||
                    const nodeid = 'node/' + domain.id + '/' + urlargs[0];
 | 
			
		||||
                    const nid = urlargs[0];
 | 
			
		||||
                    const kvmport = parent.ipKvmManager.managedPorts[nodeid];
 | 
			
		||||
                    if (kvmport == null) { next(); return; }
 | 
			
		||||
                    const kvmmanager = parent.ipKvmManager.managedGroups[kvmport.meshid];
 | 
			
		||||
                    if (kvmmanager == null) { next(); return; }
 | 
			
		||||
                    urlargs.shift();
 | 
			
		||||
                    const relurl = '/' + urlargs.join('/') + '#portId=' + kvmport.portid;
 | 
			
		||||
                    // Example: /jsclient/Client.asp#portId=P_000d5d20f64c_1
 | 
			
		||||
                    kvmmanager.fetch(relurl, null, [res, nid], function (server, args, data, rres) {
 | 
			
		||||
                        const resx = args[0], nidx = args[1];
 | 
			
		||||
                        if (rres.headers['content-type']) { resx.set('content-type', rres.headers['content-type']); }
 | 
			
		||||
 | 
			
		||||
                        // We need to replace the WebSocket code in one of the files to make it work with our server.
 | 
			
		||||
                        // Replace "b=new WebSocket(e+"//"+c+"/"+g);" in file "/js/js_kvm_client.1604062083669.min.js"
 | 
			
		||||
                        if (relurl.startsWith('/js/js_kvm_client.')) {
 | 
			
		||||
                            data = data.replace('b=new WebSocket(e+"//"+c+"/"+g);', 'b=new WebSocket(e+"//"+c+"/ipkvm.ashx/' + nidx + '/"+g);');
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        resx.end(data);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Setup MSTSC.js if needed
 | 
			
		||||
            if (domain.mstsc === true) {
 | 
			
		||||
                obj.app.get(url + 'mstsc.html', function (req, res) { handleMSTSCRequest(req, res, 'mstsc'); });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue