mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Improved remote desktop command decoding.
This commit is contained in:
		
							parent
							
								
									ecfd32f9f1
								
							
						
					
					
						commit
						7668b282bb
					
				
					 3 changed files with 46 additions and 137 deletions
				
			
		| 
						 | 
					@ -103,13 +103,13 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // KVM Control.
 | 
					    // KVM Control.
 | 
				
			||||||
    // Routines for processing incoming packets from the AJAX server, and handling individual messages.
 | 
					    // Routines for processing incoming packets from the AJAX server, and handling individual messages.
 | 
				
			||||||
    obj.ProcessPictureMsg = function (str, X, Y) {
 | 
					    obj.ProcessPictureMsg = function (data, X, Y) {
 | 
				
			||||||
        //if (obj.targetnode != null) obj.Debug("ProcessPictureMsg " + X + "," + Y + " - " + obj.targetnode.substring(0, 8));
 | 
					        //if (obj.targetnode != null) obj.Debug("ProcessPictureMsg " + X + "," + Y + " - " + obj.targetnode.substring(0, 8));
 | 
				
			||||||
        var tile = new Image();
 | 
					        var tile = new Image();
 | 
				
			||||||
        tile.xcount = obj.tilesReceived++;
 | 
					        tile.xcount = obj.tilesReceived++;
 | 
				
			||||||
        //console.log('Tile #' + tile.xcount);
 | 
					        //console.log('Tile #' + tile.xcount);
 | 
				
			||||||
        var r = obj.tilesReceived;
 | 
					        var r = obj.tilesReceived;
 | 
				
			||||||
        tile.src = "data:image/jpeg;base64," + btoa(str.substring(4, str.length));
 | 
					        tile.src = "data:image/jpeg;base64," + btoa(String.fromCharCode.apply(null, data.slice(4)));
 | 
				
			||||||
        tile.onload = function () {
 | 
					        tile.onload = function () {
 | 
				
			||||||
            //console.log('DecodeTile #' + this.xcount);
 | 
					            //console.log('DecodeTile #' + this.xcount);
 | 
				
			||||||
            if (obj.Canvas != null && obj.KillDraw < r && obj.State != 0) {
 | 
					            if (obj.Canvas != null && obj.KillDraw < r && obj.State != 0) {
 | 
				
			||||||
| 
						 | 
					@ -185,72 +185,16 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
				
			||||||
        if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight, obj.CanvasId); }
 | 
					        if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight, obj.CanvasId); }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj.ProcessData = function (str) {
 | 
					    obj.ProcessBinaryCommand = function (cmd, cmdsize, view) {
 | 
				
			||||||
        var ptr = 0;
 | 
					        var X, Y;
 | 
				
			||||||
        while (ptr < str.length) {
 | 
					        if ((cmd == 3) || (cmd == 4) || (cmd == 7)) { X = (view[4] << 8) + view[5]; Y = (view[6] << 8) + view[7]; }
 | 
				
			||||||
            var r = obj.ProcessDataEx(str.substring(ptr));
 | 
					        //console.log('CMD', cmd, cmdsize, X, Y);
 | 
				
			||||||
            if ((r == null) || (r == 0)) break;
 | 
					 | 
				
			||||||
            ptr += r;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj.ProcessDataEx = function (str) {
 | 
					        switch (cmd) {
 | 
				
			||||||
        if (obj.accumulator != null) {
 | 
					 | 
				
			||||||
            str = obj.accumulator + str;
 | 
					 | 
				
			||||||
            //console.log('KVM using accumulated data, total size is now ' + str.length + ' bytes.');
 | 
					 | 
				
			||||||
            obj.accumulator = null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); }
 | 
					 | 
				
			||||||
        if (str.length < 4) return;
 | 
					 | 
				
			||||||
        var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2), jumboAdd = 0;
 | 
					 | 
				
			||||||
        if (obj.recordedData != null) { obj.recordedData.push(recordingEntry(2, 1, str.length)); obj.recordedData.push(str); }
 | 
					 | 
				
			||||||
        if ((command == 27) && (cmdsize == 8)) {
 | 
					 | 
				
			||||||
            // Jumbo packet
 | 
					 | 
				
			||||||
            if (str.length < 12) return;
 | 
					 | 
				
			||||||
            command = ReadShort(str, 8)
 | 
					 | 
				
			||||||
            cmdsize = ReadInt(str, 4);
 | 
					 | 
				
			||||||
            //console.log('JUMBO cmd=' + command + ', cmdsize=' + cmdsize + ', data received=' + str.length);
 | 
					 | 
				
			||||||
            if ((cmdsize + 8) > str.length) {
 | 
					 | 
				
			||||||
                //console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
 | 
					 | 
				
			||||||
                obj.accumulator = str;
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            str = str.substring(8);
 | 
					 | 
				
			||||||
            jumboAdd = 8;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); }
 | 
					 | 
				
			||||||
        if ((command >= 18) && (command != 65) && (command != 88)) {
 | 
					 | 
				
			||||||
            console.error("Invalid KVM command " + command + " of size " + cmdsize);
 | 
					 | 
				
			||||||
            console.log("Invalid KVM data", str.length, rstr2hex(str.substring(0, 40)) + '...');
 | 
					 | 
				
			||||||
            if (obj.parent && obj.parent.setConsoleMessage) { obj.parent.setConsoleMessage("Received invalid network data", 5); }
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (cmdsize > str.length) {
 | 
					 | 
				
			||||||
            //console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
 | 
					 | 
				
			||||||
            obj.accumulator = str;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        //console.log("KVM Command: " + command + " Len:" + cmdsize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (command == 3 || command == 4 || command == 7) {
 | 
					 | 
				
			||||||
            cmdmsg = str.substring(4, cmdsize);
 | 
					 | 
				
			||||||
            X = ((cmdmsg.charCodeAt(0) & 0xFF) << 8) + (cmdmsg.charCodeAt(1) & 0xFF);
 | 
					 | 
				
			||||||
            Y = ((cmdmsg.charCodeAt(2) & 0xFF) << 8) + (cmdmsg.charCodeAt(3) & 0xFF);
 | 
					 | 
				
			||||||
            if (obj.debugmode > 0) { console.log("CMD" + command + " at X=" + X + " Y=" + Y); }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        switch (command) {
 | 
					 | 
				
			||||||
            case 3: // Tile
 | 
					            case 3: // Tile
 | 
				
			||||||
                if (obj.FirstDraw) obj.onResize();
 | 
					                if (obj.FirstDraw) obj.onResize();
 | 
				
			||||||
                obj.ProcessPictureMsg(cmdmsg, X, Y);
 | 
					                //console.log('TILE', X, Y);
 | 
				
			||||||
                break;
 | 
					                obj.ProcessPictureMsg(view.slice(4), X, Y);
 | 
				
			||||||
            case 4: // Tile Copy
 | 
					 | 
				
			||||||
                if (obj.FirstDraw) obj.onResize();
 | 
					 | 
				
			||||||
                if (obj.TilesDrawn == obj.tilesReceived) {
 | 
					 | 
				
			||||||
                    obj.ProcessCopyRectMsg(cmdmsg);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    obj.PendingOperations.push([ ++tilesReceived, 1, cmdmsg ]);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 7: // Screen size
 | 
					            case 7: // Screen size
 | 
				
			||||||
                obj.ProcessScreenMsg(X, Y);
 | 
					                obj.ProcessScreenMsg(X, Y);
 | 
				
			||||||
| 
						 | 
					@ -262,13 +206,13 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
				
			||||||
                obj.SendKeyMsgKC(obj.KeyAction.UP, 16); // Shift
 | 
					                obj.SendKeyMsgKC(obj.KeyAction.UP, 16); // Shift
 | 
				
			||||||
                obj.send(String.fromCharCode(0x00, 0x0E, 0x00, 0x04));
 | 
					                obj.send(String.fromCharCode(0x00, 0x0E, 0x00, 0x04));
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 11: // GetDisplays
 | 
					            case 11: // GetDisplays (TODO)
 | 
				
			||||||
                var selectedDisplay = 0, displays = { }, dcount = ((str.charCodeAt(4) & 0xFF) << 8) + (str.charCodeAt(5) & 0xFF);
 | 
					                var selectedDisplay = 0, displays = {}, dcount = (view[4] << 8) + view[5];
 | 
				
			||||||
                if (dcount > 0) {
 | 
					                if (dcount > 0) {
 | 
				
			||||||
                    // Many displays present
 | 
					                    // Many displays present
 | 
				
			||||||
                    selectedDisplay = ((str.charCodeAt(6 + (dcount * 2)) & 0xFF) << 8) + (str.charCodeAt(7 + (dcount * 2)) & 0xFF);
 | 
					                    selectedDisplay = (view[6 + (dcount * 2)] << 8) + view[7 + (dcount * 2)];
 | 
				
			||||||
                    for (var i = 0; i < dcount; i++) {
 | 
					                    for (var i = 0; i < dcount; i++) {
 | 
				
			||||||
                        var disp = ((str.charCodeAt(6 + (i * 2)) & 0xFF) << 8) + (str.charCodeAt(7 + (i * 2)) & 0xFF);
 | 
					                        var disp = (view[6 + (i * 2)] << 8) + view[7 + (i * 2)];
 | 
				
			||||||
                        if (disp == 65535) { displays[disp] = 'All Displays'; } else { displays[disp] = 'Display ' + disp; }
 | 
					                        if (disp == 65535) { displays[disp] = 'All Displays'; } else { displays[disp] = 'Display ' + disp; }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -287,17 +231,13 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
				
			||||||
            case 15: // KVM_TOUCH
 | 
					            case 15: // KVM_TOUCH
 | 
				
			||||||
                obj.TouchArray = {};
 | 
					                obj.TouchArray = {};
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 16: // MNG_KVM_CONNECTCOUNT
 | 
					 | 
				
			||||||
                obj.connectioncount = ReadInt(str, 4);
 | 
					 | 
				
			||||||
                //obj.Debug("Got KVM Connect Count: " + obj.connectioncount);
 | 
					 | 
				
			||||||
                if (obj.onConnectCountChanged != null) obj.onConnectCountChanged(obj.connectioncount, obj);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 17: // MNG_KVM_MESSAGE
 | 
					            case 17: // MNG_KVM_MESSAGE
 | 
				
			||||||
                //obj.Debug("Got KVM Message: " + str.substring(4, cmdsize));
 | 
					                var str = String.fromCharCode.apply(null, data.slice(4));
 | 
				
			||||||
                if (obj.onMessage != null) obj.onMessage(str.substring(4, cmdsize), obj);
 | 
					                obj.Debug("Got KVM Message: " + str);
 | 
				
			||||||
 | 
					                if (obj.onMessage != null) obj.onMessage(str, obj);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 65: // Alert
 | 
					            case 65: // Alert
 | 
				
			||||||
                str = str.substring(4);
 | 
					                var str = String.fromCharCode.apply(null, data.slice(4));
 | 
				
			||||||
                if (str[0] != '.') {
 | 
					                if (str[0] != '.') {
 | 
				
			||||||
                    console.log(str); //alert('KVM: ' + str);
 | 
					                    console.log(str); //alert('KVM: ' + str);
 | 
				
			||||||
                    if (obj.parent && obj.parent.setConsoleMessage) { obj.parent.setConsoleMessage(str); }
 | 
					                    if (obj.parent && obj.parent.setConsoleMessage) { obj.parent.setConsoleMessage(str); }
 | 
				
			||||||
| 
						 | 
					@ -307,13 +247,16 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 88: // MNG_KVM_MOUSE_CURSOR
 | 
					            case 88: // MNG_KVM_MOUSE_CURSOR
 | 
				
			||||||
                if (cmdsize != 5) break;
 | 
					                if (cmdsize != 5) break;
 | 
				
			||||||
                var cursorNum = str.charCodeAt(4);
 | 
					                var cursorNum = view[4];
 | 
				
			||||||
                if (cursorNum > mouseCursors.length) { cursorNum = 0; }
 | 
					                if (cursorNum > mouseCursors.length) { cursorNum = 0; }
 | 
				
			||||||
                xMouseCursorCurrent = mouseCursors[cursorNum];
 | 
					                xMouseCursorCurrent = mouseCursors[cursorNum];
 | 
				
			||||||
                if (xMouseCursorActive) { obj.CanvasId.style.cursor = xMouseCursorCurrent; }
 | 
					                if (xMouseCursorActive) { obj.CanvasId.style.cursor = xMouseCursorCurrent; }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                console.log('Unknown command', cmd, cmdsize);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return cmdsize + jumboAdd;
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Keyboard and Mouse I/O.
 | 
					    // Keyboard and Mouse I/O.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
 | 
				
			||||||
        obj.nodeid = nodeid;
 | 
					        obj.nodeid = nodeid;
 | 
				
			||||||
        obj.connectstate = 0;
 | 
					        obj.connectstate = 0;
 | 
				
			||||||
        obj.socket = new WebSocket(url);
 | 
					        obj.socket = new WebSocket(url);
 | 
				
			||||||
 | 
					        obj.socket.binaryType = 'arraybuffer';
 | 
				
			||||||
        obj.socket.onopen = obj.xxOnSocketConnected;
 | 
					        obj.socket.onopen = obj.xxOnSocketConnected;
 | 
				
			||||||
        obj.socket.onmessage = obj.xxOnMessage;
 | 
					        obj.socket.onmessage = obj.xxOnMessage;
 | 
				
			||||||
        //obj.socket.onmessage = function (e) { console.log('Websocket data', e.data); obj.xxOnMessage(e); }
 | 
					        //obj.socket.onmessage = function (e) { console.log('Websocket data', e.data); obj.xxOnMessage(e); }
 | 
				
			||||||
| 
						 | 
					@ -136,6 +137,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
 | 
				
			||||||
                    else if (typeof webkitRTCPeerConnection !== 'undefined') { obj.webrtc = new webkitRTCPeerConnection(configuration); }
 | 
					                    else if (typeof webkitRTCPeerConnection !== 'undefined') { obj.webrtc = new webkitRTCPeerConnection(configuration); }
 | 
				
			||||||
                    if ((obj.webrtc != null) && (obj.webrtc.createDataChannel)) {
 | 
					                    if ((obj.webrtc != null) && (obj.webrtc.createDataChannel)) {
 | 
				
			||||||
                        obj.webchannel = obj.webrtc.createDataChannel('DataChannel', {}); // { ordered: false, maxRetransmits: 2 }
 | 
					                        obj.webchannel = obj.webrtc.createDataChannel('DataChannel', {}); // { ordered: false, maxRetransmits: 2 }
 | 
				
			||||||
 | 
					                        obj.webchannel.binaryType = 'arraybuffer';
 | 
				
			||||||
                        obj.webchannel.onmessage = obj.xxOnMessage;
 | 
					                        obj.webchannel.onmessage = obj.xxOnMessage;
 | 
				
			||||||
                        //obj.webchannel.onmessage = function (e) { console.log('WebRTC data', e.data); obj.xxOnMessage(e); }
 | 
					                        //obj.webchannel.onmessage = function (e) { console.log('WebRTC data', e.data); obj.xxOnMessage(e); }
 | 
				
			||||||
                        obj.webchannel.onopen = function () { obj.webRtcActive = true; performWebRtcSwitch(); };
 | 
					                        obj.webchannel.onopen = function () { obj.webRtcActive = true; performWebRtcSwitch(); };
 | 
				
			||||||
| 
						 | 
					@ -165,66 +167,26 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Control messages, most likely WebRTC setup 
 | 
				
			||||||
        if (typeof e.data == 'string') {
 | 
					        if (typeof e.data == 'string') {
 | 
				
			||||||
            // Control messages, most likely WebRTC setup 
 | 
					 | 
				
			||||||
            obj.xxOnControlCommand(e.data);
 | 
					            obj.xxOnControlCommand(e.data);
 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (typeof e.data == 'object') {
 | 
					 | 
				
			||||||
            if (fileReaderInuse == true) { fileReaderAcc.push(e.data); return; }
 | 
					 | 
				
			||||||
            if (fileReader.readAsBinaryString && (obj.m.ProcessBinaryData == null)) {
 | 
					 | 
				
			||||||
                // Chrome & Firefox (Draft)
 | 
					 | 
				
			||||||
                fileReaderInuse = true;
 | 
					 | 
				
			||||||
                fileReader.readAsBinaryString(new Blob([e.data]));
 | 
					 | 
				
			||||||
            } else if (fileReader.readAsArrayBuffer) {
 | 
					 | 
				
			||||||
                // Chrome & Firefox (Spec)
 | 
					 | 
				
			||||||
                fileReaderInuse = true;
 | 
					 | 
				
			||||||
                fileReader.readAsArrayBuffer(e.data);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // IE10, readAsBinaryString does not exist, use an alternative.
 | 
					 | 
				
			||||||
                var binary = '', bytes = new Uint8Array(e.data), length = bytes.byteLength;
 | 
					 | 
				
			||||||
                for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
 | 
					 | 
				
			||||||
                obj.xxOnSocketData(binary);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // If we get a string object, it maybe the WebRTC confirm. Ignore it.
 | 
					            // Send the data to the module
 | 
				
			||||||
            obj.xxOnSocketData(e.data);
 | 
					            if (obj.m.ProcessBinaryCommand) {
 | 
				
			||||||
        }
 | 
					                // Send as Binary Command
 | 
				
			||||||
 | 
					                var view = new Uint8Array(e.data), cmd = (view[0] << 8) + view[1], cmdsize = (view[2] << 8) + view[3];
 | 
				
			||||||
        // Request RTT mesure, don't use this if WebRTC is active
 | 
					                if ((cmd == 27) && (cmdsize == 8)) { cmd = (view[8] << 8) + view[9]; cmdsize = (view[5] << 16) + (view[6] << 8) + view[7]; view = view.slice(8); }
 | 
				
			||||||
        if (obj.webRtcActive != true) {
 | 
					                if (cmdsize != view.byteLength) { console.log('REDIR-ERROR', cmd, cmdsize, view.byteLength); } else { obj.m.ProcessBinaryCommand(cmd, cmdsize, view); }
 | 
				
			||||||
            var ticks = new Date().getTime();
 | 
					            } else if (obj.m.ProcessBinaryData) {
 | 
				
			||||||
            if ((obj.latency.lastSend == null) || ((ticks - obj.latency.lastSend) > 5000)) { obj.latency.lastSend = ticks; obj.sendCtrlMsg('{"ctrlChannel":"102938","type":"rtt","time":' + ticks + '}'); }
 | 
					                // Send as Binary
 | 
				
			||||||
 | 
					                obj.m.ProcessBinaryData(new Uint8Array(e.data));
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // Send as Text
 | 
				
			||||||
 | 
					                obj.m.ProcessData(String.fromCharCode.apply(null, new Uint8Array(e.data)));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Setup the file reader
 | 
					 | 
				
			||||||
    var fileReader = new FileReader();
 | 
					 | 
				
			||||||
    var fileReaderInuse = false, fileReaderAcc = [];
 | 
					 | 
				
			||||||
    if (fileReader.readAsBinaryString && (obj.m.ProcessBinaryData == null)) {
 | 
					 | 
				
			||||||
        // Chrome & Firefox (Draft)
 | 
					 | 
				
			||||||
        fileReader.onload = function (e) { obj.xxOnSocketData(e.target.result); if (fileReaderAcc.length == 0) { fileReaderInuse = false; } else { fileReader.readAsBinaryString(new Blob([fileReaderAcc.shift()])); } }
 | 
					 | 
				
			||||||
    } else if (fileReader.readAsArrayBuffer) {
 | 
					 | 
				
			||||||
        // Chrome & Firefox (Spec)
 | 
					 | 
				
			||||||
        fileReader.onloadend = function (e) { obj.xxOnSocketData(e.target.result); if (fileReaderAcc.length == 0) { fileReaderInuse = false; } else { fileReader.readAsArrayBuffer(fileReaderAcc.shift()); } }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    obj.xxOnSocketData = function (data) {
 | 
					 | 
				
			||||||
        if (!data || obj.connectstate == -1) return;
 | 
					 | 
				
			||||||
        if (typeof data === 'object') {
 | 
					 | 
				
			||||||
            if (obj.m.ProcessBinaryData) { return obj.m.ProcessBinaryData(data); }
 | 
					 | 
				
			||||||
            // This is an ArrayBuffer, convert it to a string array (used in IE)
 | 
					 | 
				
			||||||
            var binary = '', bytes = new Uint8Array(data), length = bytes.byteLength;
 | 
					 | 
				
			||||||
            for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
 | 
					 | 
				
			||||||
            data = binary;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (typeof data !== 'string') return;
 | 
					 | 
				
			||||||
        //console.log('xxOnSocketData', rstr2hex(data));
 | 
					 | 
				
			||||||
        if ((typeof args != 'undefined') && args.redirtrace) { console.log('RedirRecv', typeof data, data.length, (data[0] == '{')?data:rstr2hex(data).substring(0, 64)); }
 | 
					 | 
				
			||||||
        return obj.m.ProcessData(data);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    obj.sendText = function (x) {
 | 
					    obj.sendText = function (x) {
 | 
				
			||||||
        if (typeof x != 'string') { x = JSON.stringify(x); } // Turn into a string if needed
 | 
					        if (typeof x != 'string') { x = JSON.stringify(x); } // Turn into a string if needed
 | 
				
			||||||
        obj.send(encode_utf8(x)); // Encode UTF8 correctly
 | 
					        obj.send(encode_utf8(x)); // Encode UTF8 correctly
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
					@ -4357,7 +4357,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
    // Authenticates a session and forwards
 | 
					    // Authenticates a session and forwards
 | 
				
			||||||
    function PerformWSSessionAuth(ws, req, noAuthOk, func) {
 | 
					    function PerformWSSessionAuth(ws, req, noAuthOk, func) {
 | 
				
			||||||
        // Check if this is a banned ip address
 | 
					        // Check if this is a banned ip address
 | 
				
			||||||
        if (obj.checkAllowLogin(req) == false) { try { ws.send(JSON.stringify({ action: 'close', cause: 'banned', msg: 'banned-1' })); ws.close(); } catch (e) { } return; }
 | 
					        if (obj.checkAllowLogin(req) == false) { parent.debug('web', 'WSERROR: Banned connection.'); try { ws.send(JSON.stringify({ action: 'close', cause: 'banned', msg: 'banned-1' })); ws.close(); } catch (e) { } return; }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            // Hold this websocket until we are ready.
 | 
					            // Hold this websocket until we are ready.
 | 
				
			||||||
            ws._socket.pause();
 | 
					            ws._socket.pause();
 | 
				
			||||||
| 
						 | 
					@ -4366,11 +4366,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
            var domain = null;
 | 
					            var domain = null;
 | 
				
			||||||
            if (noAuthOk == true) {
 | 
					            if (noAuthOk == true) {
 | 
				
			||||||
                domain = getDomain(req);
 | 
					                domain = getDomain(req);
 | 
				
			||||||
                if (domain == null) { try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'noauth-1' })); ws.close(); return; } catch (e) { } return; }
 | 
					                if (domain == null) { parent.debug('web', 'WSERROR: Got no domain, no auth ok.'); try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'noauth-1' })); ws.close(); return; } catch (e) { } return; }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // If authentication is required, enforce IP address filtering.
 | 
					                // If authentication is required, enforce IP address filtering.
 | 
				
			||||||
                domain = checkUserIpAddress(ws, req);
 | 
					                domain = checkUserIpAddress(ws, req);
 | 
				
			||||||
                if (domain == null) { return; }
 | 
					                if (domain == null) { parent.debug('web', 'WSERROR: Got no domain, user auth required.'); return; }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
 | 
					            var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
 | 
				
			||||||
| 
						 | 
					@ -4405,17 +4405,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
                                    try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', sms2fa: sms2fa, sms2fasent: true })); ws.close(); } catch (e) { }
 | 
					                                    try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', sms2fa: sms2fa, sms2fasent: true })); ws.close(); } catch (e) { }
 | 
				
			||||||
                                } else {
 | 
					                                } else {
 | 
				
			||||||
                                    // Ask for a login token
 | 
					                                    // Ask for a login token
 | 
				
			||||||
 | 
					                                    parent.debug('web', 'Asking for login token'); 
 | 
				
			||||||
                                    try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
 | 
					                                    try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                checkUserOneTimePassword(req, domain, user, req.query.token, null, function (result) {
 | 
					                                checkUserOneTimePassword(req, domain, user, req.query.token, null, function (result) {
 | 
				
			||||||
                                    if (result == false) {
 | 
					                                    if (result == false) {
 | 
				
			||||||
                                        // Failed, ask for a login token again
 | 
					                                        // Failed, ask for a login token again
 | 
				
			||||||
 | 
					                                        parent.debug('web', 'Invalid login token, asking again'); 
 | 
				
			||||||
                                        try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
 | 
					                                        try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
 | 
				
			||||||
                                    } else {
 | 
					                                    } else {
 | 
				
			||||||
                                        // We are authenticated with 2nd factor.
 | 
					                                        // We are authenticated with 2nd factor.
 | 
				
			||||||
                                        // Check email verification
 | 
					                                        // Check email verification
 | 
				
			||||||
                                        if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
 | 
					                                        if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
 | 
				
			||||||
 | 
					                                            parent.debug('web', 'Invalid login, asking for email validation'); 
 | 
				
			||||||
                                            try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
 | 
					                                            try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
 | 
				
			||||||
                                        } else {
 | 
					                                        } else {
 | 
				
			||||||
                                            func(ws, req, domain, user);
 | 
					                                            func(ws, req, domain, user);
 | 
				
			||||||
| 
						 | 
					@ -4426,6 +4429,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            // Check email verification
 | 
					                            // Check email verification
 | 
				
			||||||
                            if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
 | 
					                            if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
 | 
				
			||||||
 | 
					                                parent.debug('web', 'Invalid login, asking for email validation'); 
 | 
				
			||||||
                                try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
 | 
					                                try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                // We are authenticated
 | 
					                                // We are authenticated
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue