Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filebrowser permissions #205

Merged
merged 8 commits into from
May 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 39 additions & 84 deletions lib/agent/actions/fileretrieval/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,107 +13,62 @@ var fs = require('fs'),
common = require('./../../common'),
needle = require('needle'),
join = require('path').join,
api = require('./../../plugins/control-panel/api'),
files = require('./files_storage'),
EventEmitter = require('events').EventEmitter;
files = require('./storage'),
Emitter = require('events').EventEmitter;

var system = common.system,
config = common.config,
protocol = config._values['control-panel'].protocol,
host = config._values['control-panel'].host,
url = protocol + '://' + host,
node_bin = path.join(system.paths.current, 'bin', 'node'),
logger = common.logger,
os_name = process.platform.replace('darwin', 'mac').replace('win32', 'windows');
var system = common.system,
run_as_user = common.system.run_as_user,
node_bin = path.join(system.paths.current, 'bin', 'node'),
os_name = process.platform.replace('darwin', 'mac').replace('win32', 'windows'),
logger = common.logger;

var em,
cp;

var UPLOAD_SERVER = url + '/upload/upload',
RESUMABLE_HEADER = 'X-Prey-Upload-Resumable',
OPEN_TIMEOUT = 180000,
READ_TIMEOUT = 5000;
var path_arg,
name_arg;

// check_pending_files is used to resume any files that might been pending. It's called from
// filesagent/providers/network.
exports.check_pending_files = function() {
files.run_stored();
}

exports.start = function(options, cb) {
var file_path = options.path,
file_id = options.file_id,
file_size = parseInt(options.size),
user = options.user;

em = em || new EventEmitter();
if (cb) cb(null, em);

if (!options.resumable)
files.store(file_id, file_path, file_size, user);

var file = {
total: 0,
path: file_path,
user: user,
id: file_id,
size: file_size,
resumable: options.resumable
if (!options.resumable) {
options.resumable = false;
}

retrieve_file(file, function() {
files.del(file.id);
});
}

function retrieve_file(file, cb) {
if (file.resumable) {
var url = UPLOAD_SERVER + '?uploadID=' + file.id;
// Make a call to get the last byte processed by the upload server
// before the disconnection in order to resume the upload from that position
needle.request('get', url, null, function(err, res) {
if (err) return em.emit(err);
var data = JSON.parse(res.body);
file.total = data.Total;
get_file(file, cb);
})
return;
if (os_name == 'windows') {
path_arg = path.resolve(options.path);
name_arg = path.resolve(options.name);
} else {
path_arg = '"' + options.path + '"';
name_arg = '"' + options.name + '"';
}
get_file(file, cb);
}
var opts = {
user: options.user,
bin: node_bin,
type: 'exec',
args: [path.join(__dirname, 'upload.js'), path_arg, options.user, name_arg, options.size, options.file_id, options.resumable, options.port],
opts: {
env: process.env
}
};
em = em || new Emitter();

function get_file(file, cb) {
var buffsize = (file.size == 0) ? 1 : (file.size - file.total);
var buf = new Buffer(buffsize);
var fd = fs.openSync(file.path, "r");
files.store(options.file_id, options.path, options.size, options.user, options.name);

fs.read(fd, buf, 0, file.size - file.total, file.total, function(err, read, buf) {
if (err) return em.emit(err);
upload_file(file, buf, cb);
})
}

function upload_file(file, buf, cb) {
var options = {
open_timeout: OPEN_TIMEOUT,
read_timeout: READ_TIMEOUT
};

if (file.total > 0) {
RESUMABLE_HEADER = file.total;
}
var url = UPLOAD_SERVER + '?uploadID='+file.id;
needle.post(url, buf, options, function(err, res) {
run_as_user(opts, function(err, out) {
if (err) {
logger.error(err)
return em.emit(err);
logger.error("Upload error: " + err.message);
return;
}
logger.info("Ran as user: " + out);
if (out.indexOf("File succesfuly uploaded") != -1){
files.del(options.file_id);
}
var out = res.statusCode;
if (out !== 200 && out !== 201) {
var err = new Error('There was an error communicating with the server');
logger.error(err)
em.emit(err);
}
cb();
})
});
if (cb) cb(null, em);
em.emit('end');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@ var exist = function(id, cb) {
var key = NAMESPACE + id;
storage.all(function(err, files) {
if (err)
return logger.error(err.message);
if (files[key])
return err.message;
if (files[key])
return cb(true);
return cb(false);
})
});
}

exports.store = function(id, path, size, user) {
exports.store = function(id, path, size, user, name) {
exist(id, function(cb) {
if (cb == false) {
logger.debug('Storing file_id in DB: ' + id);
var opts = {
path: path,
size: size,
user: user
user: user,
name: name
}
storage.set(NAMESPACE + id, opts);
}
Expand All @@ -49,18 +50,18 @@ exports.run_stored = function(cb) {
var count = Object.keys(files).length;
if (count <= 0)
return;

logger.warn('Re-uploading ' + count + ' pending files.');

for (key in files) {
if(key.indexOf(NAMESPACE) != 0) {
continue;
}
var opts = {
file_id: key.substring(3, key.length),
path: files[key].path,
user: files[key].user,
name: files[key].name,
size: files[key].size,
file_id: key.substring(3, key.length),
resumable: true
}
fileretrieval.start(opts, cb);
Expand Down
130 changes: 130 additions & 0 deletions lib/agent/actions/fileretrieval/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env node

var fs = require('fs'),
path = require('path'),
mime = require('mime'),
common = require('./../../common'),
needle = require('needle');

var config = common.config,
protocol = config._values['control-panel'].protocol,
host = config._values['control-panel'].host,
url = protocol + '://' + host;

var UPLOAD_SERVER = url + '/upload/upload',
RESUMABLE_HEADER = 'X-Prey-Upload-Resumable',
OPEN_TIMEOUT = 180000,
READ_TIMEOUT = 2000;

var PATH = 2,
USER = 3,
NAME = 4,
SIZE = 5,
FILE_ID = 6,
RESUME = 7,
PORT = 8;

function main() {
var argv = process.argv;
var options = {
path: argv[PATH],
user: argv[USER],
name: argv[NAME],
size: argv[SIZE],
file_id: argv[FILE_ID],
resumable : argv[RESUME],
port: argv[PORT]
}
Main(options, function(err) {
if (err) {
console.error(err);
return;
}
});
}

function Main(options, cb) {
var file_path = options.path,
file_id = options.file_id,
file_size = parseInt(options.size),
file_name = options.name,
user = options.user;

console.log("Uploading file: ", file_path, file_id);

var file = {
total: 0,
path: file_path,
user: user,
id: file_id,
size: file_size,
resumable: options.resumable
}
retrieve_file(file, cb);
}

function retrieve_file(file, cb) {
if (file.resumable == 'true') {
console.log("Resumable file:", file.id);
var url = UPLOAD_SERVER + '?uploadID=' + file.id;
// Make a call to get the last byte processed by the upload server
// in order to resume the upload from that position.
needle.request('get', url, null, function(err, res) {
if (err) {
console.log(err);
cb(err);
return;
}
var data = JSON.parse(res.body);

file.total = data.Total;
get_file(file, cb);
})
return;
}
get_file(file, cb);
}

function get_file(file, cb) {
var buffsize = (file.size == 0) ? 1 : (file.size - file.total);
var buf = new Buffer(buffsize);
var fd = fs.openSync(file.path, "r");

fs.read(fd, buf, 0, file.size - file.total, file.total, function(err, read, buf) {
if (err) {
cb(err);
return;
}
upload_file(file, buf, cb);
})
}

function upload_file(file, buf, cb) {
var options = {
open_timeout: OPEN_TIMEOUT,
read_timeout: READ_TIMEOUT
}

if (file.total > 0) {
RESUMABLE_HEADER = file.total;
}
var url = UPLOAD_SERVER + '?uploadID=' + file.id;

needle.post(url, buf, options, function(err, res) {
if (err) {
console.log(err);
cb(err);
return;
}
var out = res.statusCode;
if (out !== 200 && out !== 201) {
var err = new Error('There was an error communicating with the server');
cb(err);
return;
}
console.log("File succesfuly uploaded:", file.id);
cb(null); // delete files
})
}

main();
2 changes: 1 addition & 1 deletion lib/agent/plugins/control-panel/api/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ exports.data = function(data, opts, cb) {

exports.report = function(data, opts, cb) {
check_keys();
var url = format_url(reports);
var url = format_url('reports');
post(url, data, opts, cb);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/agent/providers/files/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@

var fs = require('fs'),
path = require('path'),
mime = require('mime'),
winattr = require('winattr');
mime = require('mime');

var argv = process.argv,
p = argv[3],
Expand Down Expand Up @@ -110,6 +109,7 @@ directoryTreeToObj(p, cd, d, function(err, res) {

var checkIfHiddenFile = function(path, name, cb){
if (os_name == "windows") {
winattr = require('winattr');
winattr.get(path, function(err, attrs){
if (err)
return cb(false);
Expand Down