Evaluate base64-encoded commands in case of sudo

This fix makes it possible to call complex
commands that use variables with sudo by getting
rid of escaping special characters.

Change-Id: I973a6bbb244833dff84ead7e7900806031966514
Closes-Bug: #1583368
This commit is contained in:
Dmitry Nikishov 2016-05-24 09:51:39 -05:00
parent 0df5c80706
commit 30cac3f5cd
2 changed files with 13 additions and 3 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import base64
import os
import posixpath
import stat
@ -214,7 +215,10 @@ class SSHClient(object):
stderr = chan.makefile_stderr('rb')
cmd = "%s\n" % command
if self.sudo_mode:
cmd = 'sudo -S bash -c "%s"' % cmd.replace('"', '\\"')
encoded_cmd = base64.b64encode(cmd)
cmd = "sudo -S bash -c 'eval $(base64 -d <(echo \"{0}\"))'".format(
encoded_cmd
)
chan.exec_command(cmd)
if stdout.channel.closed is False:
stdin.write('%s\n' % self.password)

View File

@ -14,6 +14,7 @@
# pylint: disable=no-self-use
import base64
from contextlib import closing
from os.path import basename
import posixpath
@ -52,6 +53,7 @@ username = 'user'
password = 'pass'
private_keys = []
command = 'ls ~ '
encoded_cmd = base64.b64encode("%s\n" % command)
@mock.patch('devops.helpers.ssh_client.logger', autospec=True)
@ -340,7 +342,9 @@ class TestSSHClient(TestCase):
mock.call.makefile('wb'),
mock.call.makefile('rb'),
mock.call.makefile_stderr('rb'),
mock.call.exec_command('sudo -S bash -c "{}\n"'.format(command))
mock.call.exec_command(
"sudo -S bash -c '"
"eval $(base64 -d <(echo \"{0}\"))'".format(encoded_cmd))
))
self.assertIn(
mock.call.debug(
@ -373,7 +377,9 @@ class TestSSHClient(TestCase):
mock.call.makefile('wb'),
mock.call.makefile('rb'),
mock.call.makefile_stderr('rb'),
mock.call.exec_command('sudo -S bash -c "{}\n"'.format(command))
mock.call.exec_command(
"sudo -S bash -c '"
"eval $(base64 -d <(echo \"{0}\"))'".format(encoded_cmd))
))
self.assertIn(
mock.call.debug(