diff --git a/lib/agent/plugins/control-panel/sender.js b/lib/agent/plugins/control-panel/sender.js index 002d8ce4c..7d4be44df 100644 --- a/lib/agent/plugins/control-panel/sender.js +++ b/lib/agent/plugins/control-panel/sender.js @@ -25,7 +25,7 @@ var make_request = function(what, data, opts, cb) { // if there was an error, lets try connecting via a proxy if possible if (err && !opts.proxy && (try_proxy || '').match('.')) { opts.proxy = try_proxy; - return make_request(what, data, opts, callback); + return make_request(what, data, opts, cb); } bus.emit('response', what, err, resp); @@ -33,22 +33,18 @@ var make_request = function(what, data, opts, cb) { }); }; -var send = function(what, data, opts, callback) { +var send = function(what, data, opts, cb) { var opts = opts || {}; - if (!send_status_info || what == 'response') - return make_request(what, data, opts, callback); - var done = function(err, resp) { - if (err) { - var str = 'Got error: ' + err.message; - } else { - var str = 'Got status ' + resp.statusCode + ' from server: ' + resp.body.toString(); - } - + var str = err ? 'Got error: ' + err.message : 'Got ' + resp.statusCode + ' response: ' + resp.body.toString(); logger.info(str); + cb && cb(err, resp); } + if (!send_status_info || what == 'response') + return make_request(what, data, opts, done); + get_status_info(function(err, status) { opts.status = status; make_request(what, data, opts, done); diff --git a/lib/agent/triggers.js b/lib/agent/triggers.js index b5c8f870b..4df3126b3 100644 --- a/lib/agent/triggers.js +++ b/lib/agent/triggers.js @@ -1,6 +1,7 @@ var fs = require('fs'), join = require('path').join, actions = require('./actions'), + hooks = require('./hooks'), logger = require('./common').logger.prefix('triggers'); var watchers = [], diff --git a/lib/conf/tasks/index.js b/lib/conf/tasks/index.js old mode 100644 new mode 100755 index 53c36da6b..86c4d2a61 --- a/lib/conf/tasks/index.js +++ b/lib/conf/tasks/index.js @@ -2,8 +2,10 @@ var fs = require('fs'), async = require('async'), shared = require('./../shared'), common = require('./../../common'), + join = require('path').join, paths = common.system.paths, - os_name = process.platform.replace('win32', 'windows').replace('darwin', 'mac'); + os_name = process.platform.replace('win32', 'windows').replace('darwin', 'mac'), + chela = require('chela'); ///////////////////////////////////////////////////////////////// // local requires @@ -40,16 +42,30 @@ var set_up_config = function(cb) { } var set_up_version = function(version, cb) { + + function finish() { + // first, ensure that /current path is readable by non-prey users + // so that impersonated commands within path work as expected. + log('Setting permissions on ' + paths.current); + chela.mod(paths.current, '0755', function(err) { + if (err) return cb(err); + + // call post_activation hooks (e.g. firewall toggling in Windows) + log('Running post_activate hooks...'); + os_hooks.post_activate(cb); + }); + } + set_up_config(function(err) { if (err) return cb(err); if (!paths.versions) { // no version support, so cannot set version as current log('No versions support.'); - return os_hooks.post_activate(cb); + return finish(); } log('Setting up ' + version + ' as current...'); - shared.version_manager.set_current(version, function(err){ + shared.version_manager.set_current(version, function(err) { if (err) { if (err.code == 'ALREADY_CURRENT') log('Warning: This version is already set as current.'); @@ -57,10 +73,9 @@ var set_up_version = function(version, cb) { return cb(err); } - log('Version set. Running post_activate hooks.'); - // call post_activation hooks (e.g. firewall toggling in Windows) - os_hooks.post_activate(cb); + finish(); }); + }) } diff --git a/lib/conf/tasks/utils/create_user.sh b/lib/conf/tasks/utils/create_user.sh index 08da75e05..5c72e05d7 100755 --- a/lib/conf/tasks/utils/create_user.sh +++ b/lib/conf/tasks/utils/create_user.sh @@ -60,7 +60,7 @@ create_user() { useradd -r -M -U -G ${ADMIN_GROUP} -s $SHELL $USER_NAME for group in $groups; do - adduser $USER_NAME $group 2> /dev/null || true + usermod -a -G $group $USER_NAME 2> /dev/null || true done else diff --git a/lib/system/windows/index.js b/lib/system/windows/index.js index 48f05c884..7ee272ab2 100644 --- a/lib/system/windows/index.js +++ b/lib/system/windows/index.js @@ -55,5 +55,5 @@ exports.get_os_name = function(callback) { exports.reconnect = function(cb) { var cmd_path = path.join(__dirname, 'bin', 'autowc.exe'); - exec(cmd_path + ' -connect', cb); + exec('"' + cmd_path + '" -connect', cb); }; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b825040ed..f6d298f1b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "prey", - "version": "1.3.5", + "version": "1.3.6", "dependencies": { "async": { "version": "0.9.0", @@ -102,14 +102,14 @@ "resolved": "git://github.com/tomas/node-campfire#c4b0517ce0e49000a14ba3cedcbd9b8df2d2f8d4" }, "chela": { - "version": "0.0.3", - "from": "chela@0.0.3", - "resolved": "https://registry.npmjs.org/chela/-/chela-0.0.3.tgz", + "version": "0.0.5", + "from": "chela@0.0.5", + "resolved": "https://registry.npmjs.org/chela/-/chela-0.0.5.tgz", "dependencies": { "graceful-fs": { - "version": "3.0.4", - "from": "graceful-fs@3.0.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.4.tgz" + "version": "3.0.5", + "from": "graceful-fs@3.0.5", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.5.tgz" } } }, diff --git a/package.json b/package.json index 82901ed35..6ddb099e9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "async": "", "buckle": "0.0.3", "campfire": "git://github.com/tomas/node-campfire", - "chela": "0.0.3", + "chela": "0.0.5", "clean-exit": "0.0.3", "colors": "^0.6.2", "commander": "", diff --git a/test/lib/conf/tasks.js b/test/lib/conf/tasks.js old mode 100644 new mode 100755 index a9389e73f..f407b2766 --- a/test/lib/conf/tasks.js +++ b/test/lib/conf/tasks.js @@ -6,6 +6,7 @@ var fs = require('fs'), getset = require('getset'), rimraf = require('rimraf'), helpers = require('./../../helpers'), + chela = require('chela'), tmpdir = require('os').tmpdir(); var os_name = process.platform.replace('win32', 'windows').replace('darwin', 'mac'); @@ -23,7 +24,8 @@ var firewall = require('firewall'); describe('tasks', function() { var old_config, - old_versions_path; + old_versions_path, + chmod_stub; before(function() { process.stdout.writable = false; @@ -34,30 +36,40 @@ describe('tasks', function() { // disable version paths for these tests old_versions_path = common.system.paths.versions; common.system.paths.versions = null; - }) + + stub_chmod(); + }); after(function() { process.stdout.writable = true; common.config = old_config; common.system.paths.versions = old_versions_path; + + // release the chela.mod stub + chmod_stub.restore(); }) - if (os_name == 'windows') { + function stub_chmod() { + // stub out chela.mod so we don't accidentally chmod the source dir + chmod_stub = sinon.stub(chela, 'mod', function(path, octal, cb) { cb() }); + } - var firewall_stubs = {}; + if (os_name == 'windows') { - before(function() { - firewall_stubs.add = sinon.stub(firewall, 'add_rule', function(obj, cb) { cb() }) - firewall_stubs.del = sinon.stub(firewall, 'remove_rule', function(obj, cb) { cb() }) - }) + var firewall_stubs = {}; - after(function() { - firewall_stubs.add.restore() - firewall_stubs.del.restore(); - }) + before(function() { + firewall_stubs.add = sinon.stub(firewall, 'add_rule', function(obj, cb) { cb() }) + firewall_stubs.del = sinon.stub(firewall, 'remove_rule', function(obj, cb) { cb() }) + }) + + after(function() { + firewall_stubs.add.restore() + firewall_stubs.del.restore(); + }) - } + } describe('activate', function() { @@ -303,11 +315,62 @@ describe('tasks', function() { }) }) + it('calls chela.mod', function(done) { + tasks.activate({}, function(err) { + chmod_stub.called.should.be.true; + done(); + }); + }) + + describe('with write access to paths.current', function() { + + before(function(done) { + chmod_stub.restore(); + fs.chmod(common.system.paths.current, '0755', done); + }) + + after(stub_chmod); + + it('chmods files to 33261 (0755)', function(done) { + tasks.activate({}, function(err) { + should.not.exist(err); + fs.readdir(common.system.paths.current, function(err, list) { + var stat = fs.lstatSync(list[0]); + stat.mode.should.eql(33261); + done(); + }) + }); + }) + + }) + + describe('with NO write access to paths.current', function() { + + before(function(done) { + chmod_stub.restore(); + fs.chmod(common.system.paths.current, '0200', done); + }) + + after(function(done) { + stub_chmod(); + fs.chmod(common.system.paths.current, '0755', done); + }) + + it('returns a EPERM error', function(done) { + tasks.activate({}, function(err) { + should.exist(err); + err.code.should.eql('EACCES'); + done(); + }); + }) + + }) + }) describe('with versions support', function() { - var dir = tmpdir + '/versions'; + var dir = join(tmpdir, 'versions'); before(function() { common.system.paths.versions = dir; @@ -386,10 +449,13 @@ describe('tasks', function() { describe('and specific version dir is found', function() { - var version_dir = join(dir, '/2.3.4'); - var install_dir = join(tmpdir, 'install'); + var version_dir, install_dir; before(function(done) { + + version_dir = join(dir, '2.3.4'); + install_dir = join(tmpdir, 'install'); + fs.mkdir(version_dir, function(err) { if (err) return done(err); @@ -427,13 +493,23 @@ describe('tasks', function() { }) }) + it('does not chmod anything', function(done) { + chmod_stub.reset(); + tasks.activate({}, function(err) { + chmod_stub.called.should.be.false; + done(); + }) + }) + }) describe('with write access to install path', function() { - var current_dir = install_dir + '/current'; + var current_dir; before(function(done) { + current_dir = join(install_dir, 'current'); + common.system.paths.current = current_dir; fs.existsSync(current_dir).should.be.false; @@ -456,6 +532,22 @@ describe('tasks', function() { }) + it('chmods files to 33261 (0755)', function(done) { + + chmod_stub.restore(); + + tasks.activate({}, function(err) { + should.not.exist(err); + fs.readdir(common.system.paths.current, function(err, list) { + var stat = fs.lstatSync(list[0]); + stat.mode.should.eql(33261); + stub_chmod(); + done(); + }) + }); + + }) + }) }) @@ -484,7 +576,7 @@ describe('tasks', function() { // let's assume we have a versions path and that config.sync works // we're already testing the versions/no versions logic in .activate() old_versions_path = common.system.paths.versions; - common.system.paths.versions = tmpdir + '/versions'; + common.system.paths.versions = join(tmpdir, 'versions'); sync_stub = sinon.stub(common.config, 'sync', function(other_file, method, cb) { cb() } ) }) diff --git a/tools/build.sh b/tools/build.sh index bbaf1962f..0868a6dae 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -26,7 +26,7 @@ cleanup() { run_specs(){ echo "Ensuring we have the latest packages..." BUNDLE_ONLY=1 npm install - bin/prey test --recursive --bail --reporter dot + bin/prey test lib/agent/plugins --recursive --bail --reporter dot } create_release() {