diff --git a/lib/agent/actions/wipe/index.js b/lib/agent/actions/wipe/index.js index e8d61c70a..721679536 100644 --- a/lib/agent/actions/wipe/index.js +++ b/lib/agent/actions/wipe/index.js @@ -1,7 +1,9 @@ -var join = require('path').join, +var fs = require('fs'), + path = require('path'), Emitter = require('events').EventEmitter, wipe = require('./wipe'), common = require('./../../common'), + join = path.join, os_name = common.os_name, logger = common.logger.prefix('wipe'), system = common.system; @@ -14,13 +16,26 @@ var node_bin = join(system.paths.current, 'bin', 'node'); if (os_name == 'windows') node_bin = node_bin + '.exe'; +var validDirs = function(dirs) { + dirs = dirs.split(','); + + dirs.forEach(function(dir, index) { + dirs[index] = dir.trim(); + if (path.isAbsolute(dirs[index])) { + exports.directories.push(dirs[index]); + } else logger.info("Invalid directory path: " + dirs[index]); + }) + if (exports.directories.length == 0) return false; + return true; +} + var valid_types = function(hash) { var list = []; // hash keys should be 'wipe_cookies', 'wipe_passwords', etc for (var key in hash) { var val = hash[key].toString().trim(); - if (val == 'on' || val == 'true') { + if ((val != 'false' && val != 'off' && key.includes('wipe_')) && ( val == 'on' || val == 'true' || validDirs(val) )) { var method = key.replace('wipe_', ''); // just 'cookies' if (typeof wipe[method] == 'function') list.push(method); @@ -32,6 +47,7 @@ var valid_types = function(hash) { exports.start = function(opts, cb) { + exports.directories = []; var opts = opts || {}; var confirm = opts.confirm == 'ireallyknowwhatiamdoing'; var items = valid_types(opts); @@ -63,7 +79,7 @@ exports.start = function(opts, cb) { // run it as another process, using impersonation (to avoid permission errors) var spawn = function() { - var args = [join(__dirname, 'runner.js')].concat(items); + var args = [join(__dirname, 'runner.js')].concat(items).concat(exports.directories.toString()); system.spawn_as_logged_user(node_bin, args, function(err, child) { if (err) { @@ -80,6 +96,8 @@ exports.start = function(opts, cb) { if (line.toString().match('File removed')) { logger.warn(line.trim()); removed++; + } else if (line.toString().match('Error while removing dir')) { + logger.warn(line.trim()); } else if (line.trim() != '') { logger.debug(line.trim()); } @@ -112,7 +130,7 @@ exports.start = function(opts, cb) { emitter = new Emitter; cb(null, emitter); - spawn(); + fs.existsSync(node_bin) ? spawn() : finished(new Error('Node binary not present')); } @@ -124,3 +142,6 @@ exports.stop = function(){ emitter = null; } + +exports.valid_types = valid_types; +exports.directories = []; \ No newline at end of file diff --git a/lib/agent/actions/wipe/linux/index.js b/lib/agent/actions/wipe/linux/index.js index 2d138f927..90cce3751 100644 --- a/lib/agent/actions/wipe/linux/index.js +++ b/lib/agent/actions/wipe/linux/index.js @@ -46,5 +46,6 @@ exports.paths = { ], cloud_files: [ 'Dropbox' - ] + ], + directories: [] } diff --git a/lib/agent/actions/wipe/linux/wipe-linux b/lib/agent/actions/wipe/linux/wipe-linux old mode 100644 new mode 100755 index 3b45a8bbf..0628e1c32 Binary files a/lib/agent/actions/wipe/linux/wipe-linux and b/lib/agent/actions/wipe/linux/wipe-linux differ diff --git a/lib/agent/actions/wipe/mac/index.js b/lib/agent/actions/wipe/mac/index.js index 55f6ced7d..537a56aca 100755 --- a/lib/agent/actions/wipe/mac/index.js +++ b/lib/agent/actions/wipe/mac/index.js @@ -57,5 +57,6 @@ exports.paths = { cloud_files: [ 'Google\ Drive', 'Dropbox' - ] + ], + directories: [] } \ No newline at end of file diff --git a/lib/agent/actions/wipe/mac/wipe-osx b/lib/agent/actions/wipe/mac/wipe-osx old mode 100644 new mode 100755 index db01c9c2a..b69b446d1 Binary files a/lib/agent/actions/wipe/mac/wipe-osx and b/lib/agent/actions/wipe/mac/wipe-osx differ diff --git a/lib/agent/actions/wipe/runner.js b/lib/agent/actions/wipe/runner.js index 96a6a790f..55c197422 100755 --- a/lib/agent/actions/wipe/runner.js +++ b/lib/agent/actions/wipe/runner.js @@ -1,11 +1,16 @@ #!/usr/bin/env node -var wipe = require('./wipe'), - what = process.argv; +var wipe = require('./wipe'), + os_name = require('./../../common').os_name, + os_wipe = require('./' + os_name), + what = process.argv; // variable to store last error var last_err; +// insert custom directories in the wipe paths +os_wipe.paths.directories = what.pop().split(','); + // pad node binary and script path what.shift(); what.shift(); diff --git a/lib/agent/actions/wipe/windows/index.js b/lib/agent/actions/wipe/windows/index.js index 914451436..7b64c0969 100755 --- a/lib/agent/actions/wipe/windows/index.js +++ b/lib/agent/actions/wipe/windows/index.js @@ -85,7 +85,8 @@ exports.paths = { 'Google Drive', 'Dropbox', 'OneDrive' - ] + ], + directories: [] } /* diff --git a/lib/agent/actions/wipe/windows/wipe-win.exe b/lib/agent/actions/wipe/windows/wipe-win.exe old mode 100644 new mode 100755 index 106deb476..269bff199 Binary files a/lib/agent/actions/wipe/windows/wipe-win.exe and b/lib/agent/actions/wipe/windows/wipe-win.exe differ diff --git a/lib/agent/actions/wipe/wipe.js b/lib/agent/actions/wipe/wipe.js index 85ba2fc27..35f439b24 100755 --- a/lib/agent/actions/wipe/wipe.js +++ b/lib/agent/actions/wipe/wipe.js @@ -129,6 +129,10 @@ exports.cloud = function(cb) { }) } +exports.directories = function(cb) { + wipe('directories', cb) +} + exports.stop = function() { remover.stop(); } @@ -149,16 +153,21 @@ var wipe = function(what, cb) { --dirs || cb(last_err, removed); } - fs.readdir(root, function(err, list) { - if (err) return cb(err); - - list.forEach(function(user) { - paths[what].forEach(function(dir) { - dirs++; - remover = remove(join(root, user, dir, '*'), secure_wipe_cmd, done) - }) + if (what == 'directories') { + paths.directories.forEach(function(dir) { + dirs++; + remover = remove(join(dir, '*'), secure_wipe_cmd, done); + }) + } else { + fs.readdir(root, function(err, list) { + if (err) return cb(err); + + list.forEach(function(user) { + paths[what].forEach(function(dir) { + dirs++; + remover = remove(join(root, user, dir, '*'), secure_wipe_cmd, done) + }) + }); }); - - }); - + } } \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b8c8556d0..8bb9072f8 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -542,8 +542,8 @@ }, "remover": { "version": "0.1.2", - "from": "git://github.com/javo/remover.git#29a0254e3e07358f151efcecaa94e7451be2e05c", - "resolved": "git://github.com/javo/remover.git#29a0254e3e07358f151efcecaa94e7451be2e05c" + "from": "git://github.com/javo/remover.git#e4f53b0cc0d997e958a45f774fe8732e6a22206", + "resolved": "git://github.com/javo/remover.git#e4f53b0cc0d997e958a45f774fe8732e6a22206" }, "reply": { "version": "0.3.1", @@ -619,8 +619,8 @@ }, "satan": { "version": "0.4.3", - "from": "git://github.com/javo/satan.git#91ea6abe690bb2f2e04a0f2945bbd414af3602a3", - "resolved": "git://github.com/javo/satan.git#91ea6abe690bb2f2e04a0f2945bbd414af3602a3", + "from": "git://github.com/javo/satan.git#c6076a3f239e448e399e786a26248c37b5aba426", + "resolved": "git://github.com/javo/satan.git#c6076a3f239e448e399e786a26248c37b5aba426", "dependencies": { "launchd": { "version": "0.0.5", diff --git a/test/lib/agent/actions/wipe.js b/test/lib/agent/actions/wipe.js index 1d02c5edc..30841c6cf 100644 --- a/test/lib/agent/actions/wipe.js +++ b/test/lib/agent/actions/wipe.js @@ -5,8 +5,9 @@ var helpers = require('./../../../helpers'), os = require('os'), join = require('path').join, exec = require('child_process').exec, - wipe_path = join(lib_path, 'agent', 'actions', 'wipe', 'windows'), - wipe_win = require(wipe_path); + wipe_path = join(lib_path, 'agent', 'actions', 'wipe'), + wipe = require(wipe_path), + wipe_win = require(wipe_path + '/windows'); var outlook_versions = { old: { @@ -28,6 +29,240 @@ var registryPath = { thunderbird: join('HKEY_CLASSES_ROOT', 'ThunderbirdEML', 'DefaultIcon') }; +var hash; + +describe('wipe valid types', function() { + before(function() { + hash = { + wipe_cloud: false, + wipe_directories: false, + wipe_documents: false, + wipe_passwords: false, + wipe_cookies: false, + wipe_emails: false + } + }); + + describe('when one type is selected', function() { + + describe('and is not directories', function() { + before(function() { + hash.wipe_documents = true; + }); + after(function() { + hash.wipe_documents = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('documents'); + done(); + }) + }); + + describe('and is directories', function() { + + describe('and is only one path', function() { + describe('and the path is blank', function() { + before(function() { + hash.wipe_directories = ''; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should an empty array', function(done){ + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(0); + done(); + }) + }) + + describe('and the path is invalid', function() { + before(function() { + hash.wipe_directories = 'not a path'; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should an empty array', function(done){ + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(0); + done(); + }) + }) + + describe('and the path is valid', function() { + before(function() { + hash.wipe_directories = '/one/path/to/wipe'; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('directories'); + wipe.directories.length.should.equal(1); + wipe.directories[0].should.equal('/one/path/to/wipe'); + done(); + }) + }) + }) + + describe('and there are more than one path', function() { + describe('and one path is blank', function() { + before(function() { + hash.wipe_directories = '/one/path/to/wipe, '; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('directories'); + + wipe.directories.length.should.equal(1); + wipe.directories[0].should.equal('/one/path/to/wipe'); + done(); + }) + + }) + + describe('and one path is invalid', function() { + describe('and one path is blank', function() { + before(function() { + hash.wipe_directories = '/one/path/to/wipe, invalidpath, /another/valid/path'; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('directories'); + wipe.directories.length.should.equal(2); + wipe.directories[0].should.equal('/one/path/to/wipe'); + wipe.directories[1].should.equal('/another/valid/path'); + done(); + }) + }) + }) + + describe('and all paths are valid', function() { + before(function() { + hash.wipe_directories = '/one/path/to/wipe,/another/valid/path,/lastvalid'; + }); + after(function() { + hash.wipe_directories = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('directories'); + wipe.directories.length.should.equal(3); + wipe.directories[0].should.equal('/one/path/to/wipe'); + wipe.directories[1].should.equal('/another/valid/path'); + wipe.directories[2].should.equal('/lastvalid'); + done(); + }) + }) + }) + }) + }) + + describe('when more than one type is selected', function() { + describe('and no includes directories', function() { + before(function() { + hash.wipe_documents = true; + hash.wipe_passwords = true; + hash.wipe_emails = true; + }); + after(function() { + hash.wipe_documents = false; + hash.wipe_passwords = false; + hash.wipe_emails = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(3); + out[0].should.equal('documents'); + out[1].should.equal('passwords'); + out[2].should.equal('emails'); + done(); + }) + }); + + describe('and includes directories', function() { + describe('and the path is valid', function() { + before(function() { + hash.wipe_directories = '/valid/path'; + hash.wipe_passwords = true; + }); + after(function() { + hash.wipe_directories = false; + hash.wipe_passwords = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(2); + out[0].should.equal('directories'); + out[1].should.equal('passwords'); + wipe.directories[0].should.equal('/valid/path'); + done(); + }) + }) + describe('and the path is invalid', function() { + before(function() { + hash.wipe_directories = 'invalidpath'; + hash.wipe_passwords = true; + }); + after(function() { + hash.wipe_directories = false; + hash.wipe_passwords = false; + wipe.directories = []; + }); + + it('should return documents', function(done) { + var out = wipe.valid_types(hash); + out.should.be.Array; + out.length.should.equal(1); + out[0].should.equal('passwords'); + wipe.directories.length.should.equal(0); + done(); + }) + }) + }); + }); +}); + describe('in Windows OS', function() { var platform_stub,