certbot/certbot-apache/certbot_apache/_internal
Adrien Ferrand 50fa04ba0c
Implement umask for Windows (#7967)
This PR gets its root from an observation I did on current version of Certbot (1.3.0): the `renewal-hooks` directory in Certbot configuration directory is created on Windows with write permissions to everybody.

I thought it was a critical bug since this directory contains hooks that are executed by Certbot, and you certainly do not want this folder to be open to any malicious hook that could be inserted by everyone, then executed with administrator privileges by Certbot.

Turns out for this specific problem that the bug is not critical for the hooks, because the scripts are expected to be in subdirectories of `renewal-hooks` (namely `pre`, `post` and `deploy`), and these subdirectories have proper permissions because we set them explicitly when Certbot is starting.

Still, there is a divergence here between Linux and Windows: on Linux all Certbot directories without explicit permissions have at maximum `0o755` permissions by default, while on Windows it is a `0o777` equivalent. It is not an immediate security risk, but it is definitly error-prone, not expected, and so a potential breach in the future if we forget about it.

Root cause is that umask is not existing in Windows. Indeed under Linux the umask defines the default permissions when you create a file or a directory. Python takes that into account, with an API for `os.open` and `os.mkdir` that expose a `mode` parameter with default value of `0o777`. In practice it is never `0o777` (either you the the `mode` explictly or left the default one) because the effective mode is masked by the current umask value in the system: on Linux it is `0o022`, so files/directories have a maximum mode of `0o755` if you did not set the umask explicitly, and it is what it is observed for Certbot.

However on Windows, the `mode` value passed (and got from default) to the `open` and `mkdir` of `certbot.compat.filesystem` module is taken verbatim, since umask does not exit, and then is used to calculate the DACL of the newly created file/directory. So if the mode is not set explicitly, we end up with files and directories with `0o777` permissions.

This PR fixes this problem by implementing a umask behavior in the `certbot.compat.filesystem` module, that will be applied to any file or directory created by Certbot since we forbid to use the `os` module directly.

The implementation is quite straight-forward. For Linux the behavior is not changed. On Windows a `mask` parameter is added to the function that calculates the DACL, to be invoked appropriately when file or directory are created. The actual value of the mask is taken from an internal class of the `filesystem` module: its default value is `0o755` to match default umasks on Linux, and can be changed with the new method `umask` that have the same behavior than the original `os.umask`. Of course `os.umask` becomes a forbidden function and `filesystem.umask` must be used instead.

Existing code that is impacted have been updated, and new unit tests are created for this new function.

* Implement umask for Windows

* Set umask at the beginning of tests

* Fix lint, update local oldest requirements

* Update certbot-apache/setup.py

Co-authored-by: Brad Warren <bmw@users.noreply.github.com>

* Improve tests

* Adapt filesystem.makedirs for Windows

* Fix

* Update certbot-apache/setup.py

Co-authored-by: Brad Warren <bmw@users.noreply.github.com>

* Changelog entries

* Fix lint

* Update certbot/CHANGELOG.md

Co-authored-by: Brad Warren <bmw@users.noreply.github.com>

Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
2020-06-09 17:08:22 -07:00
..
augeas_lens Make the contents of the apache plugin private (#7579) 2019-11-25 09:44:40 -08:00
tls_configs Disable TLS session tickets in Apache (#7771) 2020-03-23 16:49:52 -07:00
__init__.py Make the contents of the apache plugin private (#7579) 2019-11-25 09:44:40 -08:00
apache_util.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00
apacheparser.py [Apache v2] Load apacheconfig tree and gate related tests (#7710) 2020-03-23 17:05:22 -07:00
assertions.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00
augeasparser.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00
configurator.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
constants.py Disable TLS session tickets in Apache (#7771) 2020-03-23 16:49:52 -07:00
display_ops.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00
dualparser.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00
entrypoint.py Cleanup more pylint issues (#7848) 2020-03-16 09:43:48 -07:00
http_01.py Implement umask for Windows (#7967) 2020-06-09 17:08:22 -07:00
interfaces.py Cleanup more pylint issues (#7848) 2020-03-16 09:43:48 -07:00
obj.py Remove useless pylint error suppression directives (#7657) 2020-02-13 13:56:16 -08:00
override_arch.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_centos.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_darwin.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_debian.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_fedora.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_gentoo.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
override_suse.py apache: handle statically linked mod_ssl (#8007) 2020-06-04 10:34:10 -07:00
parser.py Consolidate cover envs and default to py3-cover (#7905) 2020-04-16 08:59:40 -07:00
parsernode_util.py Minor bugfixes (#7891) 2020-04-13 10:41:39 -07:00