/////////////////////////////////////////////////////////////////////////////// /* intruspect.js COPYRIGHT --------- Copyright (C) 2017-2025 Mark G.Daniel Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. VERSION ------- 20-JAN-2025 MGD integrated GeoLocation 30-JAN-2017 MGD initial */ /////////////////////////////////////////////////////////////////////////////// // versions of INTRUSPECT.EXE this JavaScript is compatible with var intrsp_AcmeVersions = ['1.1.0']; var intrsp_ExeVersions = ['2.0.0']; var intrsp_ColorConnected = 'black' var intrsp_ColorDisconnected = 'red' var intrsp_ThousandComma = ','; var intrsp_ResourcePath = '/intruspect/-/'; var intrsp_LoadedFrom = location.protocol + location.host; var intrsp_AcmeIncompatible = 'JavaScript and Acme module incompatible!\n' + 'The multiple sites have cannot interwork.' var intrsp_ExeIncompatible = 'JavaScript and executable are incompatible!\n' + 'Reload and/or clear browser cache.'; var intrsp_Running = true; var intrsp_StaticData; var intrsp_GeoLocateData; /////////////////////////////////////////////////////////////////////////////// //////////////////////////// // general infrastructure // //////////////////////////// /////////////////////////////////////////////////////////////////////////////// String.prototype.htmlEscape = function() { var tagsToReplace = { '&': '&', '<': '<', '>': '>' }; return this.replace(/[&<>]/g, function(tag) { return tagsToReplace[tag] || tag; }); }; /////////////////////////////////////////////////////////////////////////////// /* Quick and dirty query string parser. Usage: var thisParam = intrspFromQuery().this_param; var thatParam = intrspFromQuery().that_param; */ var intrsp_FromQueryParams; function intrspFromQuery () { if (intrsp_FromQueryParams) return intrsp_FromQueryParams; var qs = location.search; qs = qs.substring(qs.indexOf('?')+1).split('&'); var pair; var params = {}; for (var i = qs.length - 1; i >= 0; i--) { pair = qs[i].split('='); if (pair.length != 2) continue; params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); } return (intrsp_FromQueryParams = params); } /////////////////////////////////////////////////////////////////////////////// /* Dynamically modify a stylesheet. */ function intrspCSS (selector, property, value) { for (var idx = 0; idx < document.styleSheets.length; idx++) { var sheet = document.styleSheets[idx]; try { var rule = selector + '{' + property + ':' + value + ';}'; sheet.insertRule(rule,sheet.cssRules.length); } catch(err) { try { sheet.addRule(selector,property+':'+value); } catch(err) {} } } } /////////////////////////////////////////////////////////////////////////////// //////////// // CONFIG // //////////// /////////////////////////////////////////////////////////////////////////////// // period to highlight a deleted intrusion record var intrsp_DeletedSecs = 30; // period to highlight an entry with changed count var intrsp_DeltaSecs = 30; // the period to highlight just before history deletion var intrsp_FadingSecs = 15; // period to keep entries displayed after expiry var intrsp_HistorySecs = 120; // period to highlight new entries var intrsp_NoticedSecs = 30; function configHistorySecs (secs) { intrsp_HistorySecs = secs; } function configDeletedSecs (secs) { intrsp_DeletedSecs = secs; } function configDeltaSecs (secs) { intrsp_DeltaSecs = secs; } function configFadingSecs (secs) { intrsp_FadingSecs = secs; } function configForceXHR (tf) { acmeIpcForceXHR(tf); } function configNoticedSecs (secs) { intrsp_NoticedSecs = secs; } // these are just stubs and the value is actually processed by INTRUSPECT.C function configRecordsMax () { } function configUpdateSecs () { } /////////////////////////////////////////////////////////////////////////////// ///////// // IPC // ///////// /////////////////////////////////////////////////////////////////////////////// var intrsp_StreamingData = false; function intrspStreamData (start) { // close any existing connections intrsp_StreamingData = false; acmeIpcClose(); if (!start) return; if (acmeIpcOpen()) intrsp_StreamingData = true; } /////////////////////////////////////////////////////////////////////////////// /* Receive JSON data from the executable. */ function intrspReceiveData (data) { try { data = JSON.parse(data); } catch (err) { console.log(err,data); } if (data.$data == 'alert') intrspAlert(data.time,data.message); else if (data.$data == 'intrusion') { intrsp_IntrusionData = data; } else if (data.$data == 'static') { intrsp_StaticData = data; // and add the node to the window title var json = '{"$AddToTitle":true,"node":"' + intrsp_StaticData.nodeName + '"}'; window.parent.postMessage(json,'*'); } else if (data.$data == 'geolocate') { intrsp_GeoLocateData = data; } else if (data.$data != 'runtime') { intrspAlert('DATA ERROR: '+data.$data); console.log(data); } if (intrsp_UpdateDisplay) intrspDisplaySummary(); if (intrsp_InsightDisplay) intrspDisplayInsight(data); } /////////////////////////////////////////////////////////////////////////////// /* Append this message to the alert section in the node summary area. */ function intrspAlert (time,msg) { // fixe ON for INTRUspect intrsp_AlertsDisplay = true; if (typeof msg == 'undefined') { msg = time; time = intrsp_IntrusionData['vmsTime']; } var alert = $byId('alert'); var closedAlert = $byId('closedAlert'); if (typeof msg == 'string') { if (intrsp_AlertsDisplay) { if (msg.substr(0,1) == '#') msg = msg.substr(1); if (msg.substr(0,1) == '!') var html = '' + time + ' ' + msg.substr(1) + ''; else var html = '' + time + ' ' + msg + ''; if (alert.innerHTML) alert.innerHTML += '
'; alert.innerHTML += html; closedAlert.innerHTML = html; alert.onclick = intrspAlert; } } else alert.innerHTML = closedAlert.innerHTML = ''; acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// //////////////// // data store // //////////////// /////////////////////////////////////////////////////////////////////////////// var intrsp_IntrusionData; var intrsp_StoreSeconds = 0; var intrsp_StoreTimeStamp = 0; /////////////////////////////////////////////////////////////////////////////// /////////// // print // /////////// /////////////////////////////////////////////////////////////////////////////// var intrsp_PrintClickTimer = null; var intrsp_PrintInProgress = false; var intrsp_PrintTimeout = 5; // seconds var intrsp_PrintUpdate; function intrspPrintClick () { if (intrsp_PrintInProgress) intrspAfterPrint(); else { intrspBeforePrint(); setTimeout('window.print()',100); } return true; } function intrspBeforePrint () { if (intrsp_PrintInProgress) return; intrsp_PrintInProgress = true; intrsp_PrintUpdate = intrsp_UpdateDisplay; intrspUpdateClick(false); clearTimeout(intrsp_PrintClickTimer); intrsp_PrintClickTimer = null; intrsp_PrintClickTimer = setTimeout('intrspPrintClick()',intrsp_PrintTimeout*1000); }; function intrspAfterPrint() { if (!intrsp_PrintInProgress) return; intrsp_PrintInProgress = false; clearTimeout(intrsp_PrintClickTimer); intrsp_PrintClickTimer = null; if (intrsp_PrintUpdate) intrspUpdateClick(true); }; // NOTE: this is in-line code var intrsp_MatchMedia; if (window.matchMedia) { intrsp_MatchMedia = window.matchMedia('print'); intrsp_MatchMedia.addListener(function(mql) { if (mql.matches) intrspBeforePrint(); else intrspAfterPrint(); }); } // a la MSIE window.onbeforeprint = intrspBeforePrint; window.onafterprint = intrspAfterPrint; /////////////////////////////////////////////////////////////////////////////// //////////////// // build page // //////////////// /////////////////////////////////////////////////////////////////////////////// /* */ var intrsp_OnOpenTimer = null; function intrspOnOpen () { if ($WebSocket) { $byId('sumNodeName').style.color = intrsp_ColorConnected; $byId('monitorClosed').style.color = intrsp_ColorConnected; // inform the process of the current interests var params = intrspTheseData(); acmeIpcSend(params); } else { var disc = "$byId('sumNodeName').style.color = \ $byId('monitorClosed').style.color = intrsp_ColorConnected;"; intrsp_OnOpenTimer = setTimeout(disc,2000); clearTimeout(intrsp_OnCloseTimer); intrsp_OnCloseTimer = null; } } /////////////////////////////////////////////////////////////////////////////// /* */ var intrsp_OnCloseTimer = null; function intrspOnClose () { if ($WebSocket) { $byId('sumNodeName').style.color = intrsp_ColorDisconnected; $byId('monitorClosed').style.color = intrsp_ColorDisconnected; } else { // delay a little for re-request var disc = "$byId('sumNodeName').style.color = \ $byId('monitorClosed').style.color = intrsp_ColorDisconnected;"; intrsp_OnCloseTimer = setTimeout(disc,2000); clearTimeout(intrsp_OnOpenTimer); intrsp_OnOpenTimer = null; } } /////////////////////////////////////////////////////////////////////////////// /* Primary function called by acme.js when primary JavaScript file loaded. */ function $intruspect () { acmeIpcOnOpen(intrspOnOpen); acmeIpcOnClose(intrspOnClose); acmeIpcOnMessage(intrspReceiveData); acmeLoadFile('intruspect.css'); acmeLoadFile('utf8.js'); acmeLoadFile('display.js'); acmeLoadFile('build.js','intrspBuildPage()'); } if (intrsp_AcmeVersions.indexOf($AcmeVersion) == -1) { alert(intrsp_AcmeIncompatible); throw new Error(intrsp_AcmeIncompatible); } if (intrsp_ExeVersions.indexOf($ExeVersion) == -1) { alert(intrsp_ExeIncompatible); throw new Error(intrsp_ExeIncompatible); } ///////////////////////////////////////////////////////////////////////////////