mirror of
https://github.com/certbot/certbot.git
synced 2026-06-09 00:32:12 -04:00
Strict permission checking only upon request
Use --strict-permissions if you're running as a privileged user on a system where non-privileged users might have write permissions to parts of the lets encrypt config or logging heirarchy. That should not normally be the case. Working toward a fix for #552
This commit is contained in:
parent
5709eacec4
commit
1a2c983a9c
8 changed files with 40 additions and 16 deletions
|
|
@ -129,8 +129,9 @@ class AccountFileStorage(interfaces.AccountStorage):
|
|||
|
||||
"""
|
||||
def __init__(self, config):
|
||||
le_util.make_or_verify_dir(config.accounts_dir, 0o700, os.geteuid())
|
||||
self.config = config
|
||||
le_util.make_or_verify_dir(config.accounts_dir, 0o700, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
def _account_dir_path(self, account_id):
|
||||
return os.path.join(self.config.accounts_dir, account_id)
|
||||
|
|
@ -186,7 +187,8 @@ class AccountFileStorage(interfaces.AccountStorage):
|
|||
|
||||
def save(self, account):
|
||||
account_dir_path = self._account_dir_path(account.id)
|
||||
le_util.make_or_verify_dir(account_dir_path, 0o700, os.geteuid())
|
||||
le_util.make_or_verify_dir(account_dir_path, 0o700, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
try:
|
||||
with open(self._regr_path(account_dir_path), "w") as regr_file:
|
||||
regr_file.write(account.regr.json_dumps())
|
||||
|
|
|
|||
|
|
@ -659,6 +659,10 @@ def create_parser(plugins, args):
|
|||
"security", "-r", "--redirect", action="store_true",
|
||||
help="Automatically redirect all HTTP traffic to HTTPS for the newly "
|
||||
"authenticated vhost.")
|
||||
helpful.add(
|
||||
"security", "--strict-permissions", action="store_true",
|
||||
help="Require that all configuration files are owned by the current "
|
||||
"user; use this if your config is in /tmp/")
|
||||
|
||||
_paths_parser(helpful)
|
||||
# _plugins_parsing should be the last thing to act upon the main
|
||||
|
|
@ -863,15 +867,18 @@ def main(cli_args=sys.argv[1:]):
|
|||
parser, tweaked_cli_args = create_parser(plugins, cli_args)
|
||||
args = parser.parse_args(tweaked_cli_args)
|
||||
config = configuration.NamespaceConfig(args)
|
||||
zope.component.provideUtility(config)
|
||||
|
||||
# Setup logging ASAP, otherwise "No handlers could be found for
|
||||
# logger ..." TODO: this should be done before plugins discovery
|
||||
for directory in config.config_dir, config.work_dir:
|
||||
le_util.make_or_verify_dir(
|
||||
directory, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
directory, constants.CONFIG_DIRS_MODE, os.geteuid(),
|
||||
"--strict-permissions" in cli_args)
|
||||
# TODO: logs might contain sensitive data such as contents of the
|
||||
# private key! #525
|
||||
le_util.make_or_verify_dir(args.logs_dir, 0o700, os.geteuid())
|
||||
le_util.make_or_verify_dir(
|
||||
args.logs_dir, 0o700, os.geteuid(), "--strict-permissions" in cli_args)
|
||||
_setup_logging(args)
|
||||
|
||||
# do not log `args`, as it contains sensitive data (e.g. revoke --key)!
|
||||
|
|
|
|||
|
|
@ -315,7 +315,8 @@ class Client(object):
|
|||
"""
|
||||
for path in cert_path, chain_path:
|
||||
le_util.make_or_verify_dir(
|
||||
os.path.dirname(path), 0o755, os.geteuid())
|
||||
os.path.dirname(path), 0o755, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
# try finally close
|
||||
cert_chain_abspath = None
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@ import logging
|
|||
import os
|
||||
|
||||
import OpenSSL
|
||||
import zope.component
|
||||
|
||||
from acme import crypto_util as acme_crypto_util
|
||||
from acme import jose
|
||||
|
||||
from letsencrypt import errors
|
||||
from letsencrypt import le_util
|
||||
from letsencrypt import interfaces
|
||||
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -45,8 +48,10 @@ def init_save_key(key_size, key_dir, keyname="key-letsencrypt.pem"):
|
|||
logger.exception(err)
|
||||
raise err
|
||||
|
||||
config = zope.component.getUtility(interfaces.IConfig)
|
||||
# Save file
|
||||
le_util.make_or_verify_dir(key_dir, 0o700, os.geteuid())
|
||||
le_util.make_or_verify_dir(key_dir, 0o700, os.geteuid(),
|
||||
config.strict_permissions)
|
||||
key_f, key_path = le_util.unique_file(
|
||||
os.path.join(key_dir, keyname), 0o600)
|
||||
key_f.write(key_pem)
|
||||
|
|
@ -73,8 +78,11 @@ def init_save_csr(privkey, names, path, csrname="csr-letsencrypt.pem"):
|
|||
"""
|
||||
csr_pem, csr_der = make_csr(privkey.pem, names)
|
||||
|
||||
|
||||
config = zope.component.getUtility(interfaces.IConfig)
|
||||
# Save CSR
|
||||
le_util.make_or_verify_dir(path, 0o755, os.geteuid())
|
||||
le_util.make_or_verify_dir(path, 0o755, os.geteuid(),
|
||||
config.strict_permissions)
|
||||
csr_f, csr_filename = le_util.unique_file(
|
||||
os.path.join(path, csrname), 0o644)
|
||||
csr_f.write(csr_pem)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ def exe_exists(exe):
|
|||
return False
|
||||
|
||||
|
||||
def make_or_verify_dir(directory, mode=0o755, uid=0):
|
||||
def make_or_verify_dir(directory, mode=0o755, uid=0, strict=False):
|
||||
"""Make sure directory exists with proper permissions.
|
||||
|
||||
:param str directory: Path to a directory.
|
||||
|
|
@ -89,9 +89,10 @@ def make_or_verify_dir(directory, mode=0o755, uid=0):
|
|||
os.makedirs(directory, mode)
|
||||
except OSError as exception:
|
||||
if exception.errno == errno.EEXIST:
|
||||
if not check_permissions(directory, mode, uid):
|
||||
if strict and not check_permissions(directory, mode, uid):
|
||||
raise errors.Error(
|
||||
"%s exists, this client can't access it" % directory)
|
||||
"%s exists, but it should be owned by user %d with"
|
||||
"permissions %d" % (directory, uid, oct(mode)))
|
||||
else:
|
||||
raise
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ class Reverter(object):
|
|||
self.config = config
|
||||
|
||||
le_util.make_or_verify_dir(
|
||||
config.backup_dir, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
config.backup_dir, constants.CONFIG_DIRS_MODE, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
def revert_temporary_config(self):
|
||||
"""Reload users original configuration files after a temporary save.
|
||||
|
|
@ -180,7 +181,8 @@ class Reverter(object):
|
|||
|
||||
"""
|
||||
le_util.make_or_verify_dir(
|
||||
cp_dir, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
cp_dir, constants.CONFIG_DIRS_MODE, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
op_fd, existing_filepaths = self._read_and_append(
|
||||
os.path.join(cp_dir, "FILEPATHS"))
|
||||
|
|
@ -393,7 +395,8 @@ class Reverter(object):
|
|||
cp_dir = self.config.in_progress_dir
|
||||
|
||||
le_util.make_or_verify_dir(
|
||||
cp_dir, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
cp_dir, constants.CONFIG_DIRS_MODE, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
return cp_dir
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ class Revoker(object):
|
|||
self.config = config
|
||||
self.no_confirm = no_confirm
|
||||
|
||||
le_util.make_or_verify_dir(config.cert_key_backup, 0o700, os.geteuid())
|
||||
le_util.make_or_verify_dir(config.cert_key_backup, 0o700, os.geteuid(),
|
||||
self.config.strict_permissions)
|
||||
|
||||
# TODO: Find a better solution for this...
|
||||
self.list_path = os.path.join(config.cert_key_backup, "LIST")
|
||||
|
|
@ -333,7 +334,8 @@ class Revoker(object):
|
|||
|
||||
"""
|
||||
list_path = os.path.join(config.cert_key_backup, "LIST")
|
||||
le_util.make_or_verify_dir(config.cert_key_backup, 0o700, os.geteuid())
|
||||
le_util.make_or_verify_dir(config.cert_key_backup, 0o700, os.geteuid(),
|
||||
config.strict_permissions)
|
||||
|
||||
cls._catalog_files(
|
||||
config.cert_key_backup, cert_path, key_path, list_path)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ class MakeOrVerifyDirTest(unittest.TestCase):
|
|||
|
||||
def _call(self, directory, mode):
|
||||
from letsencrypt.le_util import make_or_verify_dir
|
||||
return make_or_verify_dir(directory, mode, self.uid)
|
||||
return make_or_verify_dir(directory, mode, self.uid, strict=True)
|
||||
|
||||
def test_creates_dir_when_missing(self):
|
||||
path = os.path.join(self.root_path, "bar")
|
||||
|
|
|
|||
Loading…
Reference in a new issue