Commit 7bcad18c authored by Edvard Rejthar's avatar Edvard Rejthar

everything seems to work :o #20

parent a1c829f4
\ No newline at end of file
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at */
// @see
'use strict';
// IMPORTANT: Avoid adding any initialization tasks here, if you need to do
// something before add-on is loaded consider addon/runner module instead!
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu,
results: Cr, manager: Cm } = Components;
const ioService = Cc[';1'].
const resourceHandler = ioService.getProtocolHandler('resource').
const systemPrincipal = CC(';1', 'nsIPrincipal')();
const scriptLoader = Cc[';1'].
const prefService = Cc[';1'].
const appInfo = Cc[";1"].
const vc = Cc[";1"].
const REASON = [ 'unknown', 'startup', 'shutdown', 'enable', 'disable',
'install', 'uninstall', 'upgrade', 'downgrade' ];
const bind =;
let loader = null;
let unload = null;
let cuddlefishSandbox = null;
let nukeTimer = null;
let resourceDomains = [];
function setResourceSubstitution(domain, uri) {
resourceHandler.setSubstitution(domain, uri);
// Utility function that synchronously reads local resource from the given
// `uri` and returns content string.
function readURI(uri) {
let ioservice = Cc[';1'].
let channel = ioservice.newChannel(uri, 'UTF-8', null);
let stream =;
let cstream = Cc[';1'].
cstream.init(stream, 'UTF-8', 0, 0);
let str = {};
let data = '';
let read = 0;
do {
read = cstream.readString(0xffffffff, str);
data += str.value;
} while (read != 0);
return data;
// We don't do anything on install & uninstall yet, but in a future
// we should allow add-ons to cleanup after uninstall.
function install(data, reason) {}
function uninstall(data, reason) {}
function startup(data, reasonCode) {
try {
let reason = REASON[reasonCode];
// URI for the root of the XPI file.
// 'jar:' URI if the addon is packed, 'file:' URI otherwise.
// (Used by l10n module in order to fetch `locale` folder)
let rootURI = data.resourceURI.spec;
// TODO: Maybe we should perform read harness-options.json asynchronously,
// since we can't do anything until 'sessionstore-windows-restored' anyway.
let options = JSON.parse(readURI(rootURI + './harness-options.json'));
let id = options.jetpackID;
let name =;
// Clean the metadata
options.metadata[name]['permissions'] = options.metadata[name]['permissions'] || {};
// freeze the permissionss
// freeze the metadata
// Register a new resource 'domain' for this addon which is mapping to
// XPI's `resources` folder.
// Generate the domain name by using jetpack ID, which is the extension ID
// by stripping common characters that doesn't work as a domain name:
let uuidRe =
let domain = id.
replace(/@/g, '-at-').
replace(/\./g, '-dot-').
replace(uuidRe, '$1');
let prefixURI = 'resource://' + domain + '/';
let resourcesURI = ioService.newURI(rootURI + '/resources/', null, null);
setResourceSubstitution(domain, resourcesURI);
// Create path to URLs mapping supported by loader.
let paths = {
// Relative modules resolve to add-on package lib
'./': prefixURI + name + '/lib/',
'./tests/': prefixURI + name + '/tests/',
'': 'resource://gre/modules/commonjs/'
// Maps addon lib and tests ressource folders for each package
paths = Object.keys(options.metadata).reduce(function(result, name) {
result[name + '/'] = prefixURI + name + '/lib/'
result[name + '/tests/'] = prefixURI + name + '/tests/'
return result;
}, paths);
// We need to map tests folder when we run sdk tests whose package name
// is stripped
if (name == 'addon-sdk')
paths['tests/'] = prefixURI + name + '/tests/';
let useBundledSDK = options['force-use-bundled-sdk'];
if (!useBundledSDK) {
try {
useBundledSDK = prefService.getBoolPref("extensions.addon-sdk.useBundledSDK");
catch (e) {
// Pref doesn't exist, allow using Firefox shipped SDK
// Starting with Firefox 21.0a1, we start using modules shipped into firefox
// Still allow using modules from the xpi if the manifest tell us to do so.
// And only try to look for sdk modules in xpi if the xpi actually ship them
if (options['is-sdk-bundled'] &&
(, '21.0a1') < 0 || useBundledSDK)) {
// Maps sdk module folders to their resource folder
paths[''] = prefixURI + 'addon-sdk/lib/';
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
// until we no longer support SDK modules in XPI:
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
// Retrieve list of module folder overloads based on preferences in order to
// eventually used a local modules instead of files shipped into Firefox.
let branch = prefService.getBranch('extensions.modules.' + id + '.path');
paths = branch.getChildList('', {}).reduce(function (result, name) {
// Allows overloading of any sub folder by replacing . by / in pref name
let path = name.substr(1).split('.').join('/');
// Only accept overloading folder by ensuring always ending with `/`
if (path) path += '/';
let fileURI = branch.getCharPref(name);
// On mobile, file URI has to end with a `/` otherwise, setSubstitution
// takes the parent folder instead.
if (fileURI[fileURI.length-1] !== '/')
fileURI += '/';
// Maps the given file:// URI to a resource:// in order to avoid various
// failure that happens with file:// URI and be close to production env
let resourcesURI = ioService.newURI(fileURI, null, null);
let resName = 'extensions.modules.' + domain + '.commonjs.path' + name;
setResourceSubstitution(resName, resourcesURI);
result[path] = 'resource://' + resName + '/';
return result;
}, paths);
// Make version 2 of the manifest
let manifest = options.manifest;
// Import `cuddlefish.js` module using a Sandbox and bootstrap loader.
let cuddlefishPath = 'loader/cuddlefish.js';
let cuddlefishURI = 'resource://gre/modules/commonjs/sdk/' + cuddlefishPath;
if (paths['sdk/']) { // sdk folder has been overloaded
// (from pref, or cuddlefish is still in the xpi)
cuddlefishURI = paths['sdk/'] + cuddlefishPath;
else if (paths['']) { // root modules folder has been overloaded
cuddlefishURI = paths[''] + 'sdk/' + cuddlefishPath;
cuddlefishSandbox = loadSandbox(cuddlefishURI);
let cuddlefish = cuddlefishSandbox.exports;
// Normalize `options.mainPath` so that it looks like one that will come
// in a new version of linker.
let main = options.mainPath;
unload = cuddlefish.unload;
loader = cuddlefish.Loader({
paths: paths,
// modules manifest.
manifest: manifest,
// Add-on ID used by different APIs as a unique identifier.
id: id,
// Add-on name.
name: name,
// Add-on version.
version: options.metadata[name].version,
// Add-on package descriptor.
metadata: options.metadata[name],
// Add-on load reason.
loadReason: reason,
prefixURI: prefixURI,
// Add-on URI.
rootURI: rootURI,
// options used by system module.
// File to write 'OK' or 'FAIL' (exit code emulation).
resultFile: options.resultFile,
// Arguments passed as --static-args
staticArgs: options.staticArgs,
// Add-on preferences branch name
preferencesBranch: options.preferencesBranch,
// Arguments related to test runner.
modules: {
'@test/options': {
allTestModules: options.allTestModules,
iterations: options.iterations,
filter: options.filter,
profileMemory: options.profileMemory,
stopOnError: options.stopOnError,
verbose: options.verbose,
parseable: options.parseable,
checkMemory: options.check_memory,
let module = cuddlefish.Module('sdk/loader/cuddlefish', cuddlefishURI);
let require = cuddlefish.Require(loader, module);
require('sdk/addon/runner').startup(reason, {
loader: loader,
main: main,
prefsURI: rootURI + 'defaults/preferences/prefs.js'
} catch (error) {
dump('Bootstrap error: ' +
(error.message ? error.message : String(error)) + '\n' +
(error.stack || error.fileName + ': ' + error.lineNumber) + '\n');
throw error;
function loadSandbox(uri) {
let proto = {
sandboxPrototype: {
loadSandbox: loadSandbox,
ChromeWorker: ChromeWorker
let sandbox = Cu.Sandbox(systemPrincipal, proto);
// Create a fake commonjs environnement just to enable loading loader.js
// correctly
sandbox.exports = {};
sandbox.module = { uri: uri, exports: sandbox.exports };
sandbox.require = function (id) {
if (id !== "chrome")
throw new Error("Bootstrap sandbox `require` method isn't implemented.");
return Object.freeze({ Cc: Cc, Ci: Ci, Cu: Cu, Cr: Cr, Cm: Cm,
CC: bind(CC, Components), components: Components,
ChromeWorker: ChromeWorker });
scriptLoader.loadSubScript(uri, sandbox, 'UTF-8');
return sandbox;
function unloadSandbox(sandbox) {
if ("nukeSandbox" in Cu)
function setTimeout(callback, delay) {
let timer = Cc[";1"].createInstance(Ci.nsITimer);
timer.initWithCallback({ notify: callback }, delay,
return timer;
function shutdown(data, reasonCode) {
let reason = REASON[reasonCode];
if (loader) {
unload(loader, reason);
unload = null;
// Don't waste time cleaning up if the application is shutting down
if (reason != "shutdown") {
// Avoid leaking all modules when something goes wrong with one particular
// module. Do not clean it up immediatly in order to allow executing some
// actions on addon disabling.
// We need to keep a reference to the timer, otherwise it is collected
// and won't ever fire.
nukeTimer = setTimeout(nukeModules, 1000);
// Bug 944951 - bootstrap.js must remove the added resource: URIs on unload
resourceDomains.forEach(domain => {
resourceHandler.setSubstitution(domain, null);
function nukeModules() {
nukeTimer = null;
// module objects store `exports` which comes from sandboxes
// We should avoid keeping link to these object to avoid leaking sandboxes
for (let key in loader.modules) {
delete loader.modules[key];
// Direct links to sandboxes should be removed too
for (let key in loader.sandboxes) {
let sandbox = loader.sandboxes[key];
delete loader.sandboxes[key];
// Bug 775067: From FF17 we can kill all CCW from a given sandbox
loader = null;
// both `toolkit/loader` and `system/xul-app` are loaded as JSM's via
// `cuddlefish.js`, and needs to be unloaded to avoid memory leaks, when
// the addon is unload.
// Bug 764840: We need to unload cuddlefish otherwise it will stay alive
// and keep a reference to this compartment.
cuddlefishSandbox = null;
"abort_on_missing": false,
"check_memory": false,
"enable_e10s": false,
"is-sdk-bundled": false,
"jetpackID": "mdmaug@jetpack",
"loader": "addon-sdk/lib/sdk/loader/cuddlefish.js",
"main": "main",
"mainPath": "mdmaug/main",
"manifest": {
"mdmaug/main": {
"docsSHA256": null,
"jsSHA256": "497a1082ce489b39d8f17e63e14015b7f3ea023f4af555ccc15ef740d6f003e7",
"moduleName": "main",
"packageName": "mdmaug",
"requirements": {
"chrome": "chrome",
"sdk/base64": "sdk/base64",
"sdk/page-mod": "sdk/page-mod",
"sdk/tabs": "sdk/tabs",
"sdk/self": "sdk/self",
"sdk/tabs/utils": "sdk/tabs/utils",
"sdk/timers": "sdk/timers",
"sdk/ui/button/action": "sdk/ui/button/action",
"sdk/window/utils": "sdk/window/utils"
"sectionName": "lib"
"metadata": {
"addon-sdk": {
"description": "Add-on development made easy.",
"keywords": [
"license": "MPL 2.0",
"name": "addon-sdk"
"mdmaug": {
"author": "Edvard Rejthar",
"description": "mdmaug detection tool",
"license": "MPL 2.0",
"main": "main",
"name": "mdmaug",
"version": "0.1"
"name": "mdmaug",
"parseable": false,
"preferencesBranch": "mdmaug@jetpack",
"sdkVersion": "1.17",
"staticArgs": {},
"verbose": false
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at --><RDF xmlns="" xmlns:em="">
<Description about="urn:mozilla:install-manifest">
<!-- Firefox -->
<!-- Front End MetaData -->
<em:description>mdmaug detection tool</em:description>
<em:creator>Edvard Rejthar</em:creator>
\ No newline at end of file
......@@ -21,7 +21,7 @@ const data = require('sdk/self').data;
// **********
//profile dir
// **********
logDir = "/home/mdmaug/.cache/mdmaug-scans/_tmp/" //"/tmp/mdm/"; temp byl maly 200 MB - a zabira cennou RAMku
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);
......@@ -103,3 +103,7 @@ user_pref("toolkit.startup.max_resumed_crashes", -1);
user_pref("toolkit.telemetry.cachedClientID", "8b5a3bbc-dcb3-44f6-bd86-f0fa1fd2fa15");
user_pref("toolkit.telemetry.previousBuildID", "20170201180315");
user_pref("toolkit.telemetry.reportingpolicy.firstRun", false);
// I think these will be unuseful as of Firefox v 50+ or so
user_pref("xpinstall.signatures.required", false);
user_pref("xpinstall.whitelist.required", false);
\ No newline at end of file
# DOESNT WORK – process can know its run in docker
FROM ubuntu:16.04
#RUN apt update && apt install -y \
python3 \
python3-pip \
xvfb \
firefox \
# && pip3 install \
xvfbwrapper \
#RUN apt-get -y update && apt-get install -y fortunes
#CMD /usr/games/fortune -a | cowsay
CMD i="0";while [ $i -lt 4 ]; do echo "1";sleep 1; done
#CMD firefox
\ No newline at end of file
# Installation file for MDMaug
# If environment variable LC_ALL is empty, you may have some troubles with setting system locale as I had.
useradd -m -d $DESTINATION mdmaug
cp * /opt/mdmaug
# sometimes, there is no repository with pip on the machine, trying to add some sources
apt install software-properties-common
add-apt-repository "deb $(lsb_release -sc) main universe restricted multiverse"
apt update
apt-get install firefox python3 mariadb-server # X should be distributed with python python3-pip
pip3 install xvfbwrapper pymysql peewee jinja2 pyyaml bs4 pygments pillow requests
# mariadb setup
mysql -u root < /opt/mdmaug-installer/mdmaug-installation.sql # populate db
mysql -uroot -e "CREATE USER 'mdmaug'@'localhost' IDENTIFIED BY 'fidFDSs676'; GRANT ALL PRIVILEGES ON mdmaug. * TO 'mdmaug'@'%';" # new user
# adding user the server will be run under
useradd -m -d $DESTINATION mdmaug
# copy all important files
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
cp -r mdmaug $DESTINATION
cp -r .mozilla $DESTINATION
# copy firefox profiles (about:config is stored at prefs.js file)
for(( i=1; i<=$((PROFILE_COUNT-1)); i++ ))
[ -d $DEST ] && "profile $i already exists, wont change" || cp -R .mozilla/firefox/0 $DEST
chown mdmaug:mdmaug -R $DESTINATION
apt-get install firefox python3 python3-pip xvfb git
pip3 install xvfbwrapper pymysql
\ No newline at end of file
......@@ -4,28 +4,21 @@ Scans a website for a sign of a parasite hosts or commands.
## Installation
* ```git clone /tmp/mdmaug && /tmp/mdmaug/INSTALL```
* ```git clone /tmp/mdmaug```
* edit
* ```/tmp/mdmaug/INSTALL```
### Notes
* If you use NoScript, make sure it doesn't block the MDM-Augmented server.
* Certificate error: Make sure that the browser doesn't blockt the MDM-Augmented server if used from MDM.
* If you want other count of profiles than 21, change INSTALL + + profiles.ini
* You may put ```03 1,7,13,19 * * * ~/mdmaug-launch``` in ```crontab -e``` of user mdmaug.
## older to be distributed
Zajistim, ze na systemu bezi Firefox a nastavim mu pocet profilu, jaky chci. Podle toho upravim Config.profileCount.
Lze otestovat, ze firefox prebira z prikazove radky parametry (muze se stat, ze je stane nastaveny zastupce v /usr/bin) pri vytvareni profilu: firefox -P
## What is done to Firefox profiles?
We want no block nor safebrowsing warning. If you created the profiles manually, you'd use ```firefox -P```, the profiles names being: 0,1...
V prohlizeci, kde pojede MDMko, se pro test pripojte na a pridejte server mezi vyjimky. (Jinak se prohlížeč nepřipojí a python vrátí SSLError - unknown ca.)
Protoze MDM je pres https, je https i MDM-Augmented server. Vykaslal jsem se na certifikat, sam si jej podepsav. Zabte me.
Zabezpecte, aby NoScript neblokoval (ani
Jak ve FF vytvorit profily?
* firefox -P je vsechny vytvorim, nazvu je cisly 0,1...
* jeden profil nastavim (security - nechci zadny block ani safebrowsing warning)
* about:config
* browser.sessionstore.resume_from_crash nastavit na false
* browser.sessionstore.max_resumed_crashes nastavit na -1
......@@ -42,22 +35,16 @@ Scans a website for a sign of a parasite hosts or commands.
* privacy.sanitize.sanitizeOnShutdown = true
* privacy.clearOnShutdown.* = true
* ... see prefs.js
## older to be distributed
* mdmaug extension
- cfx xpi vygeneruje 'mdmaug.xpi'
- prejmenuju na zip
- do složky ~/.mozilla/extensions/mdmaug@jetpack (id tvori ještě přídomek @jetpack)
- vkopiruju obsah slozky zipu xpi
- prefs.js všech profilů obsahuje extensions.autoDisableScopes = "0"
* tento profile pak zkopiruju do ostatnich slozek
- about:config je v souboru prefs.js
- profily jde bezpecne prejmenovat v souboru profiles.ini
- chown: FF jede pod uzivatele mdmaug, ne pod rootem. Do Debianu se musi FF stahnout z taru. Pokud nemuze zapisovat do slozky pri vytvoreni profilu, zkusim chown mdmaug:mdmaug pro celou home slozku, nebo alespon chown mdmaug:mdmaug -hR .mozilla
- Při jednorázovém updatu prefs.js - staci kdyz ho vkopiruju do složky profilu 0, správně nastavím cesty v bin/profile_copy a spustím...
* pozor na prava, kdyztak sudo chown -R mdmaug /home/mdmaug/
- vkopiruju obsah slozky zipu xpi