/////////////////////////////////////////////////////////////////////////////// /* intruspect.js COPYRIGHT --------- Copyright (C) 2017 Mark G.Daniel This program, comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU GENERAL PUBLIC LICENSE, version 3, or any later version. http://www.gnu.org/licenses/gpl.txt VERSION ------- 30-JAN-2017 MGD initial */ /////////////////////////////////////////////////////////////////////////////// // versions of INTRUSPECT.EXE this JavaScript is compatible with var intrsp_AcmeVersions = ['1.0.0','1.1.0']; var intrsp_ExeVersions = ['1.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; /////////////////////////////////////////////////////////////////////////////// //////////////////////////// // general infrastructure // //////////////////////////// /////////////////////////////////////////////////////////////////////////////// var intrsp_MSIEversion = 0; if (navigator.appName == 'Microsoft Internet Explorer') { var ua = navigator.userAgent; var re = new RegExp('MSIE ([0-9]{1,}[\.0-9]{0,})'); if (re.exec(ua) != null) intrsp_MSIEversion = parseFloat(RegExp.$1); } 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; // default geolocation service (reference to a function) var intrsp_GeolocateService = null; 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 configGeolocateService (func) { intrsp_GeolocateService = func; } function configGeolocateFreeGeoIp (host) { geoLocateFreeGeoIp = host; } 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 != '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('display.js'); acmeLoadFile('geolocate.js'); acmeLoadFile('geolocateplus.js'); acmeLoadFile('intruspect.css'); 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); } ///////////////////////////////////////////////////////////////////////////////