Skip to content

Commit

Permalink
fix sudo to work with all shells / environments
Browse files Browse the repository at this point in the history
  • Loading branch information
pstadler committed Mar 9, 2016
1 parent 9965420 commit dddc9e8
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,10 @@ will be executed is "root". This can be changed by passing
`user: "name"` with the second argument:

```javascript
// will run: sudo -u root -i bash -c 'Hello world'
// will run: echo 'echo Hello world' | sudo -u root -i bash
transport.sudo('echo Hello world');

// will run sudo -u www -i bash -c 'Hello world'
// will run echo 'echo Hello world' | sudo -u www -i bash
transport.sudo('echo Hello world', {user: 'www'});

// further options passed (see `exec()`)
Expand Down
10 changes: 5 additions & 5 deletions lib/transport/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var format = require('util').format
, errors = require('../errors')
, commands = require('./commands')
, queue = require('../utils/queue')
, escapeQuotes = require('../utils').escapeQuotes;
, escapeSingleQuotes = require('../utils').escapeSingleQuotes;

/**
* A transport is the interface you use during flights. Basically they
Expand Down Expand Up @@ -148,10 +148,10 @@ Transport.prototype.exec = function(command, options) {
* `user: "name"` with the second argument:
*
* ```javascript
* // will run: sudo -u root -i bash -c 'Hello world'
* // will run: echo 'echo Hello world' | sudo -u root -i bash
* transport.sudo('echo Hello world');
*
* // will run sudo -u www -i bash -c 'Hello world'
* // will run echo 'echo Hello world' | sudo -u www -i bash
* transport.sudo('echo Hello world', {user: 'www'});
*
* // further options passed (see `exec()`)
Expand Down Expand Up @@ -190,8 +190,8 @@ Transport.prototype.sudo = function(command, options) {
var user = options.user || 'root';

command = format('%s%s', this._execWith, command);
command = escapeQuotes(command);
command = format("sudo -u %s -i bash -c \"'%s'\"", user, command);
command = escapeSingleQuotes(command);
command = format("echo '%s' | sudo -u %s -i bash", command, user);

return this._exec(command, options);
};
Expand Down
7 changes: 2 additions & 5 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ exports.writeTempFile = function(str) {
return fullpath;
};

exports.escapeQuotes = function(str) {
exports.escapeSingleQuotes = function(str) {
if(!str) {
return str;
}

str = str.replace(/"/g, '\\"');
str = str.replace(/'/g, "'\\''");

return str;
return str.replace(/'/g, "'\\''");
};
8 changes: 4 additions & 4 deletions test/test.transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('transport', function() {

expect(transport._exec.calledOnce).to.be.true;
expect(transport._exec.lastCall.args).to.deep.equal([
"sudo -u root -i bash -c \"''\"",
"echo '' | sudo -u root -i bash",
{}
]);
});
Expand All @@ -108,12 +108,12 @@ describe('transport', function() {
transport.sudo('printf "hello world"');

expect(transport._exec.lastCall.args[0])
.to.equal("sudo -u root -i bash -c \"\'printf \\\"hello world\\\"\'\"");
.to.equal("echo 'printf \"hello world\"' | sudo -u root -i bash");

transport.sudo("printf 'hello world'");

expect(transport._exec.lastCall.args[0])
.to.equal("sudo -u root -i bash -c \"'printf '\\''hello world'\\'''\"");
.to.equal("echo 'printf '\\''hello world'\\''' | sudo -u root -i bash");
});

it('should pass options to #_exec()', function() {
Expand All @@ -129,7 +129,7 @@ describe('transport', function() {

transport.sudo('cmd', { user: 'not-root' });

expect(transport._exec.lastCall.args[0]).to.equal("sudo -u not-root -i bash -c \"'cmd'\"");
expect(transport._exec.lastCall.args[0]).to.equal("echo 'cmd' | sudo -u not-root -i bash");
});
});

Expand Down
13 changes: 6 additions & 7 deletions test/test.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ describe('utils', function() {
});
});

describe('#escapeQuotes()', function() {
describe('#escapeSingleQuotes()', function() {
it('should correctly escape single quotes', function() {
var escapeQuotes = proxyquire('../lib/utils', {}).escapeQuotes;
var escapeSingleQuotes = proxyquire('../lib/utils', {}).escapeSingleQuotes;

expect(escapeQuotes("'string'")).to.equal("'\\''string'\\''");
expect(escapeQuotes('"string"')).to.equal('\\"string\\"');
expect(escapeQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
expect(escapeQuotes('')).to.equal('');
expect(escapeQuotes()).to.be.undefined;
expect(escapeSingleQuotes("'string'")).to.equal("'\\''string'\\''");
expect(escapeSingleQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
expect(escapeSingleQuotes('')).to.equal('');
expect(escapeSingleQuotes()).to.be.undefined;
});
});

Expand Down

0 comments on commit dddc9e8

Please sign in to comment.