Commit d80dcfce authored by Edvard Rejthar's avatar Edvard Rejthar

extension works well

parent f0ec24e8
// *****
// init
// *****
var base64 = require("sdk/base64");
var pageMod = require("sdk/page-mod");
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
const {Cr, Cc, Cu, Ci, CC} = require("chrome");
const {TextDecoder, TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
let {setTimeout} = require('sdk/timers');
let encoder = new TextEncoder(); // This encoder can be reused for several writes
// **********
//profile dir
// **********
outputDir = "/tmp/mdm/";
profile = OS.Constants.Path.profileDir;
profileName = profile.substr(profile.lastIndexOf("/") + 1);
console.log("profile name: " + profileName);
outputDir += profileName + "-log/"
OS.File.makeDir(outputDir)
// **********
// informacni button v liste nahore
// **********
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Mdmaug CZ.NIC module",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: function (state) {
alert("Mdmaug activated"); //tabs.open("https://www.mozilla.org/");
}
});
// **********
// traffic listener
// **********
trafficBlacklist = ["http://www.google.com/adsense/","https://fbstatic-a.akamaihd.net/rsrc.php", "http://clients1.google.com/ocsp", "https://safebrowsing-cache.google.com/safebrowsing/", "https://safebrowsing.google.com/safebrowsing/", "https://tiles.services.mozilla.com/"];
mimeWhitelist = ["text/html", "text/xhtml", "application/xhtml", "text/javascript", "application/javascript", "application/x-javascript"]; //mozna muze byt rozsireno
lastRequest = ""; //jeden soubor prijde v nekolika streamech za sebou
function startsWithArray(value, values) {
for (var i = 0; i < values.length; i++) {//blacklist veleznamych domen
if (value.startsWith(values[i])){
return true;
}
}
return false;
}
// SNIFFER
function TracingListener() {
//this.receivedData = [];
}
TracingListener.prototype = {
originalListener: null,
receivedData: null, // array for incoming data.
onDataAvailable: function(request, context, inputStream, offset, count){
var bis = CC("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
var ss = CC("@mozilla.org/storagestream;1", "nsIStorageStream");
var binaryInputStream = new bis();
var storageStream = new ss();
binaryInputStream.setInputStream(inputStream);
storageStream.init(8192, count, null);
var bo = CC("@mozilla.org/binaryoutputstream;1","nsIBinaryOutputStream");
var binaryOutputStream = new bo();
binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
// Copy received data as they come.
var data = binaryInputStream.readBytes(count);
//loggovani stranek, o ktere stojime
if (startsWithArray(request.getResponseHeader("Content-Type"), mimeWhitelist) && !startsWithArray(request.originalURI.spec, trafficBlacklist)) {//safebrowsing nas nezajima a je ho na kazde strance plno
//if (1){ //XXX XXX XXX
//ulozit nactenou stranku
//console.error("current last", request.originalURI.spec, lastRequest);//XX debug
if (request.originalURI.spec != lastRequest) {//novy request, vytisknout do souboru hlavicku
lastRequest = request.originalURI.spec;
//console.error("request", request.originalURI.spec);
header = request.originalURI.spec + " " + request.getResponseHeader("Content-Type") + "\n";
//console.error("("+profileName+") " + header);//xx debug
} else {
header = ""; //preskakujeme hlavicku
}
filename = request.originalURI.spec.replace(/[^a-z0-9]/gi, '').substring(0, 50).toLowerCase() + ".tmp";
//append_log_text(outputDir + profileName + ".txt", header + data);
//console.error("the file",outputDir + filename);
append_log_text(outputDir + filename, header + data);
}
//console.log("data",data);
//
//console.log(data);
binaryOutputStream.writeBytes(data, count);
this.originalListener.onDataAvailable(request, context, storageStream.newInputStream(0), offset, count);
},
onStartRequest: function(request, context) {
this.receivedData = [];
this.originalListener.onStartRequest(request, context);
},
onStopRequest: function(request, context, statusCode)
{
/* try XX Zde selhavala metoda parseQuery. Mozna kvulito tomu ted nezachytim postRequesty. Kod jsem vzal mozna odsud: http://stackoverflow.com/questions/2167203/ns-error-failure
{
request.QueryInterface(Ci.nsIHttpChannel);
if (request.originalURI)
{
// console.log("HUUUUUUUUUU",Date.parse(request.getResponseHeader("Date")));
var data = null;
if (request.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request, context);
if (postText)
data = ((String)(postText)).parseQuery();
}
var date = Date.parse(request.getResponseHeader("Date"));
var responseSource = this.receivedData.join('');
//fix leading spaces bug
responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1");
// console.log(request.originalURI.spec);
}
}
catch (e)
{
console.error("error", e);
} */
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
},
readPostTextFromRequest : function(request, context) {
try
{
var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Ci.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
dump("Failed to Query Interface for upload stream.\n"); //dump console.error
}
}
catch (exc)
{
dumpError(exc);// console.error dumpError(exc);
}
return null;
},
readFromStream : function(stream, charset, noClose) {
var sis = CCSV("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
}
hRO = { observe: function(request, aTopic, aData){
try {
if (aTopic == "http-on-examine-response") {
request.QueryInterface(Ci.nsIHttpChannel);
if (request.originalURI) {
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = request.setNewListener(newListener);
}
}
} catch (e) {
console.log("\nhRO error: \n\tMessage: " + e.message + "\n\tFile: " + e.fileName + " line: " + e.lineNumber + "\n");
}
},
QueryInterface: function(aIID){
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
},
};
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(hRO,
"http-on-examine-response", false);
// */
//
// LOG TO FILE
//
function append_log_text(filename, text) {
var encoder = new TextEncoder();
var data = encoder.encode(text);
filename = OS.Path.join(OS.Constants.Path.tmpDir, filename);
Task.spawn(function() {
let file = yield OS.File.open(filename, {write: true});
yield file.write(data);
yield file.close();
//console.log("written to", filename);
}).then(null, function(e) console.error(e));
}
//presmerovani na prvni strance
pageMod.PageMod({
include: "http://localhost/*",
//kdyz zacina na "localhost/redirect/", je to jen presmerovani
//contentScript: "alert(55);if(location.href.indexOf('http://localhost/redirect/') == 0) {location.href = location.href.substr(26);}",
});
/*
// script sniffer: kazda stranka uda presny kod
// - Ale neuda ho ajaxem nacteny skript.!
pageMod.PageMod({
include: "*",
contentScript: "self.postMessage({filename: location.hostname, loc: location.href, doc:document.documentElement.outerHTML});",
onMessage: function (data) {
console.log("new page");
append_log_text(outputDir + "foooooo.txt", data.loc + "\n" + data.doc + "\n");
}
});
*/
// **********
// screenshot: finalni stranka (kam nas to donaviguje), se vyfoti
// **********
screenshotted = false;
function screenshot(){
if (screenshotted == true) {//screenshot muze byt zavolat 2× - kdyz je tab ready a kdyz nam dojde trpelivost
return false;
} else {
screenshotted = true;
}
console.log("Starting screenshot countdown...");
setTimeout(function () {
var window = require('sdk/window/utils').getMostRecentBrowserWindow();
var tab = require('sdk/tabs/utils').getActiveTab(window);
var myData;
tabs.activeTab.attach({
contentScript: "self.postMessage(Math.max(document.body.scrollHeight, document.body.offsetHeight,document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight));", //recieves the total scroll height of tab
onMessage: function (height) {
console.log("Screenshot data received");
/*
//zdrojova data - save all
Ulozi jen konecny stav, ale nikoli redirecty.
mediator = Cc['@mozilla.org/appshell/window-mediator;1'],
gBrowser = mediator.getService(Ci.nsIWindowMediator).getMostRecentWindow('navigator:browser').gBrowser,
callback = function (aProgress, aRequest, aURI) { console.log(aURI.spec); };
var file = "/tmp/test/result.htm";
var dataFolder = "/tmp/test/result.htms";
localFile = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsILocalFile);
localFile.initWithPath(file)
dataPath = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsILocalFile)
dataPath.initWithPath(dataFolder)
persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Ci.nsIWebBrowserPersist);
persist.saveDocument(gBrowser.contentDocument, localFile, dataPath, null, null, null);
*/
//screenshot
//return;
var thumbnail = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
window = tab.linkedBrowser.contentWindow;
thumbnail.width = window.screen.availWidth;
thumbnail.height = window.screen.availHeight;
var ctx = thumbnail.getContext("2d");
var snippetWidth = window.outerWidth;
var snippetHeight = window.outerHeight;
ctx.canvas.left = 0;
ctx.canvas.top = 0;
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = height; //canvas height is made equal to the scroll height of window
ctx.drawWindow(window, 0, 0, snippetWidth, snippetHeight + height, "rgb(255,255,255)"); //
ctx.scale(0.5, 0.5);
var imageDataUri = thumbnail.toDataURL('image/png');//'image/png'
//
//imageDataUri = imageDataUri.replace("image/png", "image/octet-stream");
//imageDataUri = imageDataUri.replace("data:image/png;base64,", "");
let promise2 = OS.File.writeAtomic(outputDir + "screenshot_debug.html",
encoder.encode("<img src='" + imageDataUri + "' />"), {
tmpPath: outputDir + profileName + "-screenshot_debug.html.tmp"
});
imageDataUri = imageDataUri.replace(/^data:image\/(png|jpg);base64,/, "");
let promise = OS.File.writeAtomic(outputDir + "screenshot_base64.txt", //outputDir + profileName + "-screenshot_base64.html"
// //encoder.encode("<img src='" + imageDataUri + "' />"), {
encoder.encode(imageDataUri), {
//imageDataUri,{
tmpPath: outputDir + profileName + "-screenshot_base64.txt.tmp"
});
console.log("Screenshot data generated");
//tabs.open(imageDataUri);
// **********
//quit firefox
// **********
Cc['@mozilla.org/toolkit/app-startup;1'].getService(Ci.nsIAppStartup).quit(Ci.nsIAppStartup.eAttemptQuit)
}
});
}, 5000);
};
/* XXX XXX XXX
setTimeout(function () {
//pokud stranka neni ready, dosla nam trpelivost
screenshot();
}, 5000);*/
//Cu.import("resource://gre/modules/devtools/Console.jsm");
// Prvni presmerovani
//stoppa = false;
tabs.on('ready', function () {
//console.error("tab ready?");
//Protoze se prvni nacitana stranka zacne nacitat rychleji , nez tento addon, prvni request na root neprojde mym snifferem.
// (Nedelo se to vzdy, jen casto. Zřejmě vnitřní procesy FF, nějaký heartbeat.)
//console.error(tabs[0].url, (tabs[0].url.indexOf("http://localhost/redirect/") == 0), "presmeruju");
if(tabs[0].url.indexOf("http://localhost/redirect/") == 0) {//kdyz zacina na "localhost/redirect/", je to jen presmerovani
//console.error("OPPPPPPPPPPPPPPPPPPP");
//tabs[0].url = tabs[0].url.substr(26); //preskocit na cilovou lokaci
//if(stoppa == false) {
// stoppa = true;
//tabs.open("http://1pupik1989.707.cz/");
//tabs.open("http://1pupik1989.707.cz/");
//tabs.open("http://seznam.cz");
//tabs.open(tabs[0].url.substr(26)); //preskocit na cilovou lokaci)
//setTimeout(function(){
tabs[0].url = tabs[0].url.substr(26);
// tabs.open("http://seznam.cz");
//tabs.open("http://1pupik1989.707.cz/");
//},1000);
//}
} else {
screenshot();
}
});
// *****
// init
// Mdmaug extension
// *****
var base64 = require("sdk/base64");
var pageMod = require("sdk/page-mod");
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
const base64 = require("sdk/base64");
const pageMod = require("sdk/page-mod");
const buttons = require('sdk/ui/button/action');
const tabs = require("sdk/tabs");
const data = require('sdk/self').data;
const {Cr, Cc, Cu, Ci, CC} = require("chrome");
const {TextDecoder, TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
const {setTimeout} = require('sdk/timers');
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const WAIT_FOR_READY = 5000;
const WAIT_FOR_SCREENSHOT = 5000;
let profileDir = OS.Constants.Path.profileDir;
let profileName = profileDir.substr(profileDir.lastIndexOf("/") + 1);
let logDir = "/tmp/mdmaug/.cache/mdmaug-scans/_tmp/" + profileName + "-log/"; // /tmp/ is small (200 MB) and takes precious RAM
let cacheDir = logDir; //defaultni dir, kam ulozime analyzu je log dir, pokud se nam nepodari zjistit, kam jinam mame cache dat
console.error("Profile name: " + profileName);
launchCacheDirCheck();
launchButtonDecorator();
launchTracingListener();
launchSpyfiles();
launchScreenshot();
if (tabs[0].url.indexOf("http://localhost/redirect/") === 0) {//kdyz zacina na "localhost/redirect/", je to jen presmerovani
//Protoze se prvni nacitana stranka zacne nacitat rychleji , nez tento addon, prvni request na root neprojde mym snifferem.
// (Nedelo se to vzdy, jen casto (!). Zřejmě vnitřní procesy FF, nějaký heartbeat.)
//Tento blok kodu se v 'tabs.on(ready)' obsas nespustil (!). Davam ho mimo
tabs[0].url = tabs[0].url.substr(26);
}
const {Cr, Cc, Cu, Ci, CC} = require("chrome");
const {TextDecoder, TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
let {setTimeout} = require('sdk/timers');
let encoder = new TextEncoder(); // This encoder can be reused for several writes
//const self = require("self");
//disabled EDVARD XXX
// **********
//profile dir
// **********
logDir = "/opt/mdmaug/.cache/mdmaug-scans/_tmp/" //"/tmp/mdm/"; temp byl maly 200 MB - a zabira cennou RAMku
profileDir = OS.Constants.Path.profileDir;
profileName = profileDir.substr(profileDir.lastIndexOf("/") + 1);
console.log("profile name: " + profileName);
logDir += profileName + "-log/"
OS.File.makeDir(logDir)
cacheDir = logDir //defaultni dir, kam ulozime analyzu je log dir, pokud se nam nepodari zjistit, kam jinam mame cache dat
let decoder = new TextDecoder();
let promise = OS.File.read(logDir + "cache.dir");
promise = promise.then(
function onSuccess(array) {
cacheDir = decoder.decode(array); // Python server nam poslal zpravu, kde cacheDir je
OS.File.makeDir(cacheDir) // kdyby nahodou neexistoval
}
);
//*****************
// LOG TO FILE
//*****************
function append_log_text(filename, text) {
var encoder = new TextEncoder();
var data = encoder.encode(text);
filename = OS.Path.join(OS.Constants.Path.tmpDir, filename);
Task.spawn(function () {
let file = yield OS.File.open(filename, {write: true});
yield file.write(data);
yield file.close();
//console.log("written to", filename);
}).then(null, function (e) console.error(e)
);
}
// **********
// informacni button v liste nahore
// **********
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Mdmaug CZ.NIC module",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: function (state) {
alert("Mdmaug activated"); //tabs.open("https://www.mozilla.org/");
}
});
// **********
// my helping functions
// **********
trafficBlacklist = ["http://www.google.com/adsense/", "https://fbstatic-a.akamaihd.net/rsrc.php", "http://clients1.google.com/ocsp", "https://safebrowsing-cache.google.com/safebrowsing/", "https://safebrowsing.google.com/safebrowsing/", "https://tiles.services.mozilla.com/"];
mimeWhitelist = ["text/html", "text/xhtml", "application/xhtml", "text/javascript", "application/javascript", "application/x-javascript"]; //mozna muze byt rozsireno
lastRequest = ""; //jeden soubor prijde v nekolika streamech za sebou
/*************************
* HOISTED FUNCTIONS *****
*************************/
function startsWithArray(value, values) {
for (var i = 0; i < values.length; i++) {//blacklist veleznamych domen
if (value.startsWith(values[i])) {
return true;
function launchCacheDirCheck() {
OS.File.makeDir(logDir); // assure dir exists
OS.File.read(logDir + "cache.dir").then(
function onSuccess(array) {
cacheDir = decoder.decode(array); // Python server nam poslal zpravu, kde cacheDir je
OS.File.makeDir(cacheDir); // kdyby nahodou neexistoval
}
);
}
/**
* informative button in the upper bar
*/
function launchButtonDecorator() {
buttons.ActionButton({
id: "mozilla-link",
label: "Mdmaug CZ.NIC module",
icon: {//XX not found now
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: function (state) {
alert("Mdmaug is activated");
}
}
return false;
});
}
/**
* traffic listener
*/
function launchTracingListener() {
let trafficBlacklist = ["http://www.google.com/adsense/", "https://fbstatic-a.akamaihd.net/rsrc.php", "http://clients1.google.com/ocsp", "https://safebrowsing-cache.google.com/safebrowsing/", "https://safebrowsing.google.com/safebrowsing/", "https://tiles.services.mozilla.com/"];
let mimeWhitelist = ["text/html", "text/xhtml", "application/xhtml", "text/javascript", "application/javascript", "application/x-javascript"]; //mozna muze byt rozsireno
let lastRequest = ""; // a file may come in several streams consecutively
function url2filename(url, extension) {
if (extension == undefined) {
extension = "tmp";
function TracingListener() {
}
return url.replace(/[^a-z0-9]/gi, '').substring(0, 50).toLowerCase() + "." + extension;
}
// *****************
// traffic listener
// ****************
TracingListener.prototype = {
originalListener: null,
receivedData: null, // array for incoming data.
onDataAvailable: function (request, context, inputStream, offset, count) {
var bis = CC("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
var ss = CC("@mozilla.org/storagestream;1", "nsIStorageStream");
var binaryInputStream = new bis();
var storageStream = new ss();
binaryInputStream.setInputStream(inputStream);
storageStream.init(8192, count, null);
var bo = CC("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream");
var binaryOutputStream = new bo();
binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
// Copy received data as they come.
var data = binaryInputStream.readBytes(count);
//loggovani stranek, o ktere stojime
if (startsWithArray(request.getResponseHeader("Content-Type"), mimeWhitelist) && !startsWithArray(request.originalURI.spec, trafficBlacklist)) {//safebrowsing nas nezajima a je ho na kazde strance plno
//if (1){
//ulozit nactenou stranku
//console.error("current last", request.originalURI.spec, lastRequest);//XX debug
if (request.originalURI.spec != lastRequest) {//novy request, vytisknout do souboru hlavicku
lastRequest = request.originalURI.spec;