pmbootstrap/test
Oliver Smith 3666388619
Properly escape commands in pmb.chroot.user() (#1316)
## Introduction
In #1302 we noticed that `pmb.chroot.user()` does not escape commands
properly: When passing one string with spaces, it would pass them as
two strings to the chroot. The use case is passing a description with
a space inside to `newapkbuild` with `pmboostrap newapkbuild`.

This is not a security issue, as we don't pass strings from untrusted
input to this function.

## Functions for running commands in pmbootstrap
To put the rest of the description in context: We have four high level
functions that run commands:
* `pmb.helpers.run.user()`
* `pmb.helpers.run.root()`
* `pmb.chroot.root()`
* `pmb.chroot.user()`

In addition, one low level function that the others invoke:
* `pmb.helpers.run.core()`

## Flawed test case
The issue described above did not get detected for so long, because we
have a test case in place since day one, which verifies that all of the
functions above escape everything properly:
* `test/test_shell_escape.py`

So the test case ran a given command through all these functions, and
compared the result each time. However, `pmb.chroot.root()`
modified the command variable (passed by reference) and did the
escaping already, which means `pmb.chroot.user()` running directly
afterwards only returns the right output when *not* doing any escaping.

Without questioning the accuracy of the test case, I've escaped
commands and environment variables with `shlex.quote()` *before*
passing them to `pmb.chroot.user()`. In retrospective this does not
make sense at all and is reverted with this commit.

## Environment variables
By coincidence, we have only passed custom environment variables to
`pmb.chroot.user()`, never to the other high level functions. This only
worked, because we did not do any escaping and the passed line gets
executed as shell command:
```
$ MYENV=test echo test2
test 2
```
If it was properly escaped as one shell command:
```
$ 'MYENV=test echo test2'
sh: MYENV=test echo test2: not found
```
So doing that clearly doesn't work anymore. I have added a new `env`
parameter to `pmb.chroot.user()` (and to all other high level functions
for consistency), where environment variables can be passed as a
dictionary. Then the function knows what to do and we end up with
properly escaped commands and environment variables.

## Details
* Add new `env` parameter to all high level command execution functions
* New `pmb.helpers.run.flat_cmd()` function, that takes a command as
  list and environment variables as dict, and creates a properly escaped
  flat string from the input.
* Use that function for proper escaping in all high level exec funcs
* Don't escape commands *before* passing them to `pmb.chroot.user()`
* Describe parameters of the command execution functions
* `pmbootstrap -v` writes the exact command to the log that was
  executed (in addition to the simplified form we always write down for
  readability)
* `test_shell_escape.py`: verify that the command passed by reference
  has not been modified, add a new test for strings with spaces, add
  tests for new function `pmb.helpers.run.flat_cmd()`
* Remove obsolete commend in `pmb.chroot.distccd` about environment
  variables, because we don't use any there anymore
* Add `TERM=xterm` to default environment variables in the chroot,
  so running ncurses applications like `menuconfig` and `nano` works out of
  the box
2018-03-10 22:58:39 +00:00
..
testdata Skip virtual packages when parsing APKINDEX (#1278) 2018-03-10 13:15:30 +00:00
check_checksums.py check_checksums.py: Non-zero exit on build error 2018-02-14 00:12:46 +01:00
static_code_analysis.sh static_code_analysis.sh: Find CHANGEMEs in APKBUILDs (#1161) 2018-01-24 21:31:07 +00:00
test_apk_static.py Index parser: support multiple package providers (#1202) 2018-02-20 19:52:28 +00:00
test_aportgen.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_aportgen_device_wizard.py deviceinfo: remove external_disk_install and external_disk, use external_storage instead (#1301) 2018-03-07 22:35:02 +00:00
test_aports.py Make nonfree depends optional part 2: device pkgs (#1268) 2018-02-26 22:11:44 +00:00
test_bootimg.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_build_is_necessary.py Index parser: support multiple package providers (#1202) 2018-02-20 19:52:28 +00:00
test_build_package.py Properly escape commands in pmb.chroot.user() (#1316) 2018-03-10 22:58:39 +00:00
test_buildroot_aarch64_init.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_chroot_interactive_shell.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_config_user.py Remove timestamp based rebuilds (#1174) 2018-01-28 23:27:33 +00:00
test_file.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_folder_size.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_frontend.py pmbootstrap build --src: override source for any package (#1210) 2018-02-19 22:04:01 +00:00
test_install.py Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) 2018-02-24 21:49:10 +00:00
test_keys.py Index parser: support multiple package providers (#1202) 2018-02-20 19:52:28 +00:00
test_mount.py Happy new year! (update copyright to 2018) 2018-01-04 04:53:35 +01:00
test_newapkbuild.py Wrap Alpine's newapkbuild (#894) 2018-01-15 22:00:11 +00:00
test_parse_apkbuild.py Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) 2018-02-24 21:49:10 +00:00
test_parse_apkindex.py Skip virtual packages when parsing APKINDEX (#1278) 2018-03-10 13:15:30 +00:00
test_parse_depends.py Index parser: support multiple package providers (#1202) 2018-02-20 19:52:28 +00:00
test_pkgrel_bump.py Remove timestamp based rebuilds (#1174) 2018-01-28 23:27:33 +00:00
test_qemu_running_processes.py Testsuite: Run UIs in Qemu and check running processes and more (#982) 2018-02-02 00:16:29 +00:00
test_questions.py Make proprietary drivers optional (1/2): pmbootstrap changes (#1254) 2018-02-24 21:49:10 +00:00
test_repo.py Remove rest of 'pmbootstrap challenge' left overs (#1173) 2018-02-01 22:03:21 +00:00
test_shell_escape.py Properly escape commands in pmb.chroot.user() (#1316) 2018-03-10 22:58:39 +00:00
test_soname_bump.py Gracefully handle packages breaking because of soname bumps (#1116) 2018-01-14 01:26:42 +00:00
test_upstream_compatibility.py Only download APKINDEX for relevant architectures (#1201) 2018-03-04 13:44:27 +00:00
test_version.py Testsuite: Run UIs in Qemu and check running processes and more (#982) 2018-02-02 00:16:29 +00:00
test_version_validate.py version.py: fix validation of 6.0_0002 (#1160) 2018-01-25 18:23:55 +00:00
testcases_fast.sh Testsuite: Run UIs in Qemu and check running processes and more (#982) 2018-02-02 00:16:29 +00:00