From db1726941394a9126538c8c8afd66bc07ec458a1 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Thu, 8 Sep 2016 09:58:03 -0400 Subject: [PATCH 01/10] Add login shell wrapper --- lib/train/extras/command_wrapper.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index 5685ccc8..1d1af737 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -29,6 +29,7 @@ class LinuxCommand < CommandWrapperBase Train::Options.attach(self) option :sudo, default: false + option :login, default: false option :sudo_options, default: nil option :sudo_password, default: nil option :sudo_command, default: nil @@ -39,11 +40,11 @@ def initialize(backend, options) validate_options(options) @sudo = options[:sudo] + @login = options[:login] @sudo_options = options[:sudo_options] @sudo_password = options[:sudo_password] @sudo_command = options[:sudo_command] @user = options[:user] - @prefix = build_prefix end # (see CommandWrapperBase::verify) @@ -71,7 +72,7 @@ def verify # (see CommandWrapperBase::run) def run(command) - @prefix + command + login_wrap(sudo_wrap(command)) end def self.active?(options) @@ -80,9 +81,9 @@ def self.active?(options) private - def build_prefix - return '' unless @sudo - return '' if @user == 'root' + def sudo_wrap(cmd) + return cmd unless @sudo + return cmd if @user == 'root' res = (@sudo_command || 'sudo') + ' ' @@ -93,7 +94,12 @@ def build_prefix res << @sudo_options.to_s + ' ' unless @sudo_options.nil? - res + res + cmd + end + + def login_wrap(cmd) + return cmd unless @login + "$SHELL -l <<< \"#{cmd}\"" end end From 5058023da798a26a369b80fe67a7f04eb6722b38 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Thu, 8 Sep 2016 10:06:58 -0400 Subject: [PATCH 02/10] Add tests for login wrapping --- test/unit/extras/command_wrapper_test.rb | 84 ++++++++++++++---------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index 178b4816..31d2f7e7 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -16,47 +16,61 @@ backend } - it 'wraps commands in sudo' do - lc = cls.new(backend, { sudo: true }) - lc.run(cmd).must_equal "sudo #{cmd}" - end + describe 'sudo wrapping' do + it 'wraps commands in sudo' do + lc = cls.new(backend, { sudo: true }) + lc.run(cmd).must_equal "sudo #{cmd}" + end - it 'doesnt wrap commands in sudo if user == root' do - lc = cls.new(backend, { sudo: true, user: 'root' }) - lc.run(cmd).must_equal cmd - end + it 'doesnt wrap commands in sudo if user == root' do + lc = cls.new(backend, { sudo: true, user: 'root' }) + lc.run(cmd).must_equal cmd + end - it 'wraps commands in sudo with all options' do - opts = rand.to_s - lc = cls.new(backend, { sudo: true, sudo_options: opts }) - lc.run(cmd).must_equal "sudo #{opts} #{cmd}" - end + it 'wraps commands in sudo with all options' do + opts = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_options: opts }) + lc.run(cmd).must_equal "sudo #{opts} #{cmd}" + end - it 'runs commands in sudo with password' do - pw = rand.to_s - lc = cls.new(backend, { sudo: true, sudo_password: pw }) - bpw = Base64.strict_encode64(pw + "\n") - lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | sudo -S #{cmd}" - end + it 'runs commands in sudo with password' do + pw = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_password: pw }) + bpw = Base64.strict_encode64(pw + "\n") + lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | sudo -S #{cmd}" + end - it 'wraps commands in sudo_command instead of sudo' do - sudo_command = rand.to_s - lc = cls.new(backend, { sudo: true, sudo_command: sudo_command }) - lc.run(cmd).must_equal "#{sudo_command} #{cmd}" - end + it 'wraps commands in sudo_command instead of sudo' do + sudo_command = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_command: sudo_command }) + lc.run(cmd).must_equal "#{sudo_command} #{cmd}" + end + + it 'wraps commands in sudo_command with all options' do + opts = rand.to_s + sudo_command = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_command: sudo_command, sudo_options: opts }) + lc.run(cmd).must_equal "#{sudo_command} #{opts} #{cmd}" + end - it 'wraps commands in sudo_command with all options' do - opts = rand.to_s - sudo_command = rand.to_s - lc = cls.new(backend, { sudo: true, sudo_command: sudo_command, sudo_options: opts }) - lc.run(cmd).must_equal "#{sudo_command} #{opts} #{cmd}" + it 'runs commands in sudo_command with password' do + pw = rand.to_s + sudo_command = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_command: sudo_command, sudo_password: pw }) + bpw = Base64.strict_encode64(pw + "\n") + lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | #{sudo_command} -S #{cmd}" + end end - it 'runs commands in sudo_command with password' do - pw = rand.to_s - sudo_command = rand.to_s - lc = cls.new(backend, { sudo: true, sudo_command: sudo_command, sudo_password: pw }) - bpw = Base64.strict_encode64(pw + "\n") - lc.run(cmd).must_equal "echo #{bpw} | base64 --decode | #{sudo_command} -S #{cmd}" + describe 'login wrapping' do + it 'wraps commands in login' do + lc = cls.new(backend, { login: true }) + lc.run(cmd).must_equal "$SHELL -l <<< \"#{cmd}\"" + end + + it 'wraps sudo commands in a login shell' do + lc = cls.new(backend, { sudo: true, login: true }) + lc.run(cmd).must_equal "$SHELL -l <<< \"sudo #{cmd}\"" + end end end From b4213f2a18728b97e6ac3767749b944249370a0c Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Thu, 8 Sep 2016 10:08:16 -0400 Subject: [PATCH 03/10] Ignore frozen string literal comments in rubocop --- .rubocop.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 081749a6..c24d32c3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -69,3 +69,5 @@ Style/SpaceAroundOperators: Enabled: false Style/IfUnlessModifier: Enabled: false +Style/FrozenStringLiteralComment: + Enabled: false From 388ebe31d6fc44d92d83cea9d63fac2165a75892 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Thu, 8 Sep 2016 12:44:39 -0400 Subject: [PATCH 04/10] Add a shell option and tests --- lib/train/extras/command_wrapper.rb | 18 ++++++++---- test/unit/extras/command_wrapper_test.rb | 35 ++++++++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index 1d1af737..cc56a04d 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -40,6 +40,7 @@ def initialize(backend, options) validate_options(options) @sudo = options[:sudo] + @shell = options[:shell] @login = options[:login] @sudo_options = options[:sudo_options] @sudo_password = options[:sudo_password] @@ -72,11 +73,15 @@ def verify # (see CommandWrapperBase::run) def run(command) - login_wrap(sudo_wrap(command)) + shell_wrap(sudo_wrap(command)) end def self.active?(options) - options.is_a?(Hash) && options[:sudo] + options.is_a?(Hash) && ( + options[:sudo] || + options[:shell] || + options[:login] + ) end private @@ -97,9 +102,12 @@ def sudo_wrap(cmd) res + cmd end - def login_wrap(cmd) - return cmd unless @login - "$SHELL -l <<< \"#{cmd}\"" + def shell_wrap(cmd) + return cmd unless @shell || @login + login_param = '--login ' if @login + shell = @shell.instance_of?(String) ? @shell : '$SHELL' + + "#{shell} #{login_param}<<< \"#{cmd}\"" end end diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index 31d2f7e7..27a8dbd8 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -62,15 +62,40 @@ end end - describe 'login wrapping' do - it 'wraps commands in login' do + describe 'shell wrapping' do + it 'wraps commands in a default shell with login' do lc = cls.new(backend, { login: true }) - lc.run(cmd).must_equal "$SHELL -l <<< \"#{cmd}\"" + lc.run(cmd).must_equal "$SHELL --login <<< \"#{cmd}\"" end - it 'wraps sudo commands in a login shell' do + it 'wraps sudo commands in a default shell with login' do lc = cls.new(backend, { sudo: true, login: true }) - lc.run(cmd).must_equal "$SHELL -l <<< \"sudo #{cmd}\"" + lc.run(cmd).must_equal "$SHELL --login <<< \"sudo #{cmd}\"" + end + + it 'wraps commands in a default shell when shell is true' do + lc = cls.new(backend, { shell: true }) + lc.run(cmd).must_equal "$SHELL <<< \"#{cmd}\"" + end + + it 'doesnt wrap commands in a shell when shell is false' do + lc = cls.new(backend, { shell: false }) + lc.run(cmd).must_equal cmd + end + + it 'wraps commands in a shell when shell is false, but login is true' do + lc = cls.new(backend, { shell: false, login: true }) + lc.run(cmd).must_equal "$SHELL --login <<< \"#{cmd}\"" + end + + it 'wraps commands in a `shell` instead of default shell' do + lc = cls.new(backend, { shell: '/bin/bash' }) + lc.run(cmd).must_equal "/bin/bash <<< \"#{cmd}\"" + end + + it 'wraps commands in a default shell with login' do + lc = cls.new(backend, { shell: '/bin/bash', login: true }) + lc.run(cmd).must_equal "/bin/bash --login <<< \"#{cmd}\"" end end end From 0af1653033da9cef646992d93717b29b0db4d9cf Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Fri, 9 Sep 2016 10:08:40 -0400 Subject: [PATCH 05/10] Add shell option --- lib/train/extras/command_wrapper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index cc56a04d..64ed4471 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -29,6 +29,7 @@ class LinuxCommand < CommandWrapperBase Train::Options.attach(self) option :sudo, default: false + option :shell, default: false option :login, default: false option :sudo_options, default: nil option :sudo_password, default: nil From 175c14c8b96f837fc94df609c5bc60f7ab208889 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Fri, 16 Sep 2016 10:51:44 -0400 Subject: [PATCH 06/10] Change shell options to be similar to sudo options, add comments --- lib/train/extras/command_wrapper.rb | 26 ++++++++++++++---------- test/unit/extras/command_wrapper_test.rb | 23 ++++++++------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index 64ed4471..8d0ab199 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -28,9 +28,11 @@ def run(_command) class LinuxCommand < CommandWrapperBase Train::Options.attach(self) - option :sudo, default: false + option :shell, default: false - option :login, default: false + option :shell_options, default: nil + option :shell_command, default: nil + option :sudo, default: false option :sudo_options, default: nil option :sudo_password, default: nil option :sudo_command, default: nil @@ -40,9 +42,10 @@ def initialize(backend, options) @backend = backend validate_options(options) - @sudo = options[:sudo] @shell = options[:shell] - @login = options[:login] + @shell_options = options[:shell_options] # e.g. '--login' + @shell_command = options[:shell_command] # e.g. '/bin/sh' + @sudo = options[:sudo] @sudo_options = options[:sudo_options] @sudo_password = options[:sudo_password] @sudo_command = options[:sudo_command] @@ -80,13 +83,13 @@ def run(command) def self.active?(options) options.is_a?(Hash) && ( options[:sudo] || - options[:shell] || - options[:login] + options[:shell] ) end private + # wrap the cmd in a sudo command def sudo_wrap(cmd) return cmd unless @sudo return cmd if @user == 'root' @@ -103,12 +106,13 @@ def sudo_wrap(cmd) res + cmd end + # wrap the cmd in a subshell allowing for options to + # passed to the subshell def shell_wrap(cmd) - return cmd unless @shell || @login - login_param = '--login ' if @login - shell = @shell.instance_of?(String) ? @shell : '$SHELL' - - "#{shell} #{login_param}<<< \"#{cmd}\"" + return cmd unless @shell + shell = @shell_command || '$SHELL' + options = @shell_options.to_s + ' ' unless @shell_options.nil? + "#{shell} #{options}<<< '#{cmd}'" end end diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index 27a8dbd8..e3ff30fc 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -64,18 +64,18 @@ describe 'shell wrapping' do it 'wraps commands in a default shell with login' do - lc = cls.new(backend, { login: true }) - lc.run(cmd).must_equal "$SHELL --login <<< \"#{cmd}\"" + lc = cls.new(backend, { shell: true, shell_options: '--login' }) + lc.run(cmd).must_equal "$SHELL --login <<< '#{cmd}'" end it 'wraps sudo commands in a default shell with login' do - lc = cls.new(backend, { sudo: true, login: true }) - lc.run(cmd).must_equal "$SHELL --login <<< \"sudo #{cmd}\"" + lc = cls.new(backend, { sudo: true, shell: true, shell_options: '--login' }) + lc.run(cmd).must_equal "$SHELL --login <<< 'sudo #{cmd}'" end it 'wraps commands in a default shell when shell is true' do lc = cls.new(backend, { shell: true }) - lc.run(cmd).must_equal "$SHELL <<< \"#{cmd}\"" + lc.run(cmd).must_equal "$SHELL <<< '#{cmd}'" end it 'doesnt wrap commands in a shell when shell is false' do @@ -83,19 +83,14 @@ lc.run(cmd).must_equal cmd end - it 'wraps commands in a shell when shell is false, but login is true' do - lc = cls.new(backend, { shell: false, login: true }) - lc.run(cmd).must_equal "$SHELL --login <<< \"#{cmd}\"" - end - it 'wraps commands in a `shell` instead of default shell' do - lc = cls.new(backend, { shell: '/bin/bash' }) - lc.run(cmd).must_equal "/bin/bash <<< \"#{cmd}\"" + lc = cls.new(backend, { shell: true, shell_command: '/bin/bash' }) + lc.run(cmd).must_equal "/bin/bash <<< '#{cmd}'" end it 'wraps commands in a default shell with login' do - lc = cls.new(backend, { shell: '/bin/bash', login: true }) - lc.run(cmd).must_equal "/bin/bash --login <<< \"#{cmd}\"" + lc = cls.new(backend, { shell: true, shell_command: '/bin/bash', shell_options: '--login' }) + lc.run(cmd).must_equal "/bin/bash --login <<< '#{cmd}'" end end end From 57a47b56e4df85863a9297fa02d85e4a79784d64 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Fri, 16 Sep 2016 11:00:53 -0400 Subject: [PATCH 07/10] <<< is a bash specific operator --- lib/train/extras/command_wrapper.rb | 4 ++-- test/unit/extras/command_wrapper_test.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index 8d0ab199..a38f557e 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -111,8 +111,8 @@ def sudo_wrap(cmd) def shell_wrap(cmd) return cmd unless @shell shell = @shell_command || '$SHELL' - options = @shell_options.to_s + ' ' unless @shell_options.nil? - "#{shell} #{options}<<< '#{cmd}'" + options = ' ' + @shell_options.to_s unless @shell_options.nil? + "echo '#{cmd}' > #{shell}#{options}" end end diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index e3ff30fc..11a66c29 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -65,17 +65,17 @@ describe 'shell wrapping' do it 'wraps commands in a default shell with login' do lc = cls.new(backend, { shell: true, shell_options: '--login' }) - lc.run(cmd).must_equal "$SHELL --login <<< '#{cmd}'" + lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL --login" end it 'wraps sudo commands in a default shell with login' do lc = cls.new(backend, { sudo: true, shell: true, shell_options: '--login' }) - lc.run(cmd).must_equal "$SHELL --login <<< 'sudo #{cmd}'" + lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL --login" end it 'wraps commands in a default shell when shell is true' do lc = cls.new(backend, { shell: true }) - lc.run(cmd).must_equal "$SHELL <<< '#{cmd}'" + lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL" end it 'doesnt wrap commands in a shell when shell is false' do @@ -85,12 +85,12 @@ it 'wraps commands in a `shell` instead of default shell' do lc = cls.new(backend, { shell: true, shell_command: '/bin/bash' }) - lc.run(cmd).must_equal "/bin/bash <<< '#{cmd}'" + lc.run(cmd).must_equal "echo '#{cmd}' > /bin/bash" end it 'wraps commands in a default shell with login' do lc = cls.new(backend, { shell: true, shell_command: '/bin/bash', shell_options: '--login' }) - lc.run(cmd).must_equal "/bin/bash --login <<< '#{cmd}'" + lc.run(cmd).must_equal "echo '#{cmd}' > /bin/bash --login" end end end From 5f5211d44263f772d8165a937ef2c81f88550cb7 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Tue, 20 Sep 2016 09:54:04 -0400 Subject: [PATCH 08/10] Fix test --- test/unit/extras/command_wrapper_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index 11a66c29..813accb7 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -70,7 +70,7 @@ it 'wraps sudo commands in a default shell with login' do lc = cls.new(backend, { sudo: true, shell: true, shell_options: '--login' }) - lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL --login" + lc.run(cmd).must_equal "echo 'sudo #{cmd}' > $SHELL --login" end it 'wraps commands in a default shell when shell is true' do From b8859a1cfc5d34078f76f37b7c9b048653af5881 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Tue, 20 Sep 2016 10:59:48 -0400 Subject: [PATCH 09/10] Use base64 --- lib/train/extras/command_wrapper.rb | 16 +++++++++++----- test/unit/extras/command_wrapper_test.rb | 24 +++++++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index a38f557e..964f636d 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -96,10 +96,7 @@ def sudo_wrap(cmd) res = (@sudo_command || 'sudo') + ' ' - unless @sudo_password.nil? - b64pw = Base64.strict_encode64(@sudo_password + "\n") - res = "echo #{b64pw} | base64 --decode | #{res}-S " - end + res = "#{safe_string(@sudo_password + "\n")} | #{res}-S " unless @sudo_password.nil? res << @sudo_options.to_s + ' ' unless @sudo_options.nil? @@ -110,9 +107,18 @@ def sudo_wrap(cmd) # passed to the subshell def shell_wrap(cmd) return cmd unless @shell + shell = @shell_command || '$SHELL' options = ' ' + @shell_options.to_s unless @shell_options.nil? - "echo '#{cmd}' > #{shell}#{options}" + + "#{safe_string(cmd)} | #{shell}#{options}" + end + + # encapsulates encoding the string into a safe form, and decoding for use. + # @return [String] A command line snippet that can be used as part of a pipeline. + def safe_string(str) + b64str = Base64.strict_encode64(str) + "echo #{b64str} | base64 --decode" end end diff --git a/test/unit/extras/command_wrapper_test.rb b/test/unit/extras/command_wrapper_test.rb index 813accb7..539cd5dc 100644 --- a/test/unit/extras/command_wrapper_test.rb +++ b/test/unit/extras/command_wrapper_test.rb @@ -65,17 +65,29 @@ describe 'shell wrapping' do it 'wraps commands in a default shell with login' do lc = cls.new(backend, { shell: true, shell_options: '--login' }) - lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL --login" + bcmd = Base64.strict_encode64(cmd) + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | $SHELL --login" end it 'wraps sudo commands in a default shell with login' do lc = cls.new(backend, { sudo: true, shell: true, shell_options: '--login' }) - lc.run(cmd).must_equal "echo 'sudo #{cmd}' > $SHELL --login" + bcmd = Base64.strict_encode64("sudo #{cmd}") + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | $SHELL --login" + end + + it 'wraps sudo commands and sudo passwords in a default shell with login' do + pw = rand.to_s + lc = cls.new(backend, { sudo: true, sudo_password: pw, shell: true, shell_options: '--login' }) + bpw = Base64.strict_encode64(pw + "\n") + bcmd = Base64.strict_encode64("echo #{bpw} | base64 --decode | sudo -S #{cmd}") + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | $SHELL --login" + p bcmd end it 'wraps commands in a default shell when shell is true' do lc = cls.new(backend, { shell: true }) - lc.run(cmd).must_equal "echo '#{cmd}' > $SHELL" + bcmd = Base64.strict_encode64(cmd) + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | $SHELL" end it 'doesnt wrap commands in a shell when shell is false' do @@ -85,12 +97,14 @@ it 'wraps commands in a `shell` instead of default shell' do lc = cls.new(backend, { shell: true, shell_command: '/bin/bash' }) - lc.run(cmd).must_equal "echo '#{cmd}' > /bin/bash" + bcmd = Base64.strict_encode64(cmd) + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | /bin/bash" end it 'wraps commands in a default shell with login' do lc = cls.new(backend, { shell: true, shell_command: '/bin/bash', shell_options: '--login' }) - lc.run(cmd).must_equal "echo '#{cmd}' > /bin/bash --login" + bcmd = Base64.strict_encode64(cmd) + lc.run(cmd).must_equal "echo #{bcmd} | base64 --decode | /bin/bash --login" end end end From 8e9eb42e5741fc481c38bbfd5166d6614ae945c5 Mon Sep 17 00:00:00 2001 From: "Morley, Jonathan" Date: Tue, 20 Sep 2016 11:55:00 -0400 Subject: [PATCH 10/10] Satisfy rubocop --- lib/train/extras/command_wrapper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/train/extras/command_wrapper.rb b/lib/train/extras/command_wrapper.rb index 964f636d..558c14d9 100644 --- a/lib/train/extras/command_wrapper.rb +++ b/lib/train/extras/command_wrapper.rb @@ -28,7 +28,6 @@ def run(_command) class LinuxCommand < CommandWrapperBase Train::Options.attach(self) - option :shell, default: false option :shell_options, default: nil option :shell_command, default: nil