mirror of
https://github.com/certbot/certbot.git
synced 2026-08-02 03:11:55 +02:00
Change default privkey permissions while preserving group permissions (#6480)
Fixes #1473. writes privkey.pem to 0600 by default for new lineages on renewals where a new privkey is generated, preserves group mode and gid Things this PR does not do: we talked about forcing 0600 on privkeys when a Certbot upgrade is detected. Instead, this PR only creates new lineages with the more restrictive permission to prevent renewal breakages. this doesn't solve many of the problems mentioned in #1473 that are not directly related to the title issue! * safe_open on archive keyfiles * keep group from current lineage * clean up integration test * safe_open can follow symlinks * fix tests on windows, maybe * Address Brad's comments * Revert changes to safe_open * Test chown is called when saving new key * Reorder chown operation * Changelog and documentation * Fix documentation style
This commit is contained in:
+16
-6
@@ -29,6 +29,7 @@ logger = logging.getLogger(__name__)
|
||||
ALL_FOUR = ("cert", "privkey", "chain", "fullchain")
|
||||
README = "README"
|
||||
CURRENT_VERSION = util.get_strict_version(certbot.__version__)
|
||||
BASE_PRIVKEY_MODE = 0o600
|
||||
|
||||
|
||||
def renewal_conf_files(config):
|
||||
@@ -1050,13 +1051,14 @@ class RenewableCert(object):
|
||||
# Put the data into the appropriate files on disk
|
||||
target = dict([(kind, os.path.join(live_dir, kind + ".pem"))
|
||||
for kind in ALL_FOUR])
|
||||
archive_target = dict([(kind, os.path.join(archive, kind + "1.pem"))
|
||||
for kind in ALL_FOUR])
|
||||
for kind in ALL_FOUR:
|
||||
os.symlink(os.path.join(_relpath_from_file(archive, target[kind]), kind + "1.pem"),
|
||||
target[kind])
|
||||
os.symlink(_relpath_from_file(archive_target[kind], target[kind]), target[kind])
|
||||
with open(target["cert"], "wb") as f:
|
||||
logger.debug("Writing certificate to %s.", target["cert"])
|
||||
f.write(cert)
|
||||
with open(target["privkey"], "wb") as f:
|
||||
with util.safe_open(archive_target["privkey"], "wb", chmod=BASE_PRIVKEY_MODE) as f:
|
||||
logger.debug("Writing private key to %s.", target["privkey"])
|
||||
f.write(privkey)
|
||||
# XXX: Let's make sure to get the file permissions right here
|
||||
@@ -1120,14 +1122,15 @@ class RenewableCert(object):
|
||||
os.path.join(self.archive_dir, "{0}{1}.pem".format(kind, target_version)))
|
||||
for kind in ALL_FOUR])
|
||||
|
||||
old_privkey = os.path.join(
|
||||
self.archive_dir, "privkey{0}.pem".format(prior_version))
|
||||
|
||||
# Distinguish the cases where the privkey has changed and where it
|
||||
# has not changed (in the latter case, making an appropriate symlink
|
||||
# to an earlier privkey version)
|
||||
if new_privkey is None:
|
||||
# The behavior below keeps the prior key by creating a new
|
||||
# symlink to the old key or the target of the old key symlink.
|
||||
old_privkey = os.path.join(
|
||||
self.archive_dir, "privkey{0}.pem".format(prior_version))
|
||||
if os.path.islink(old_privkey):
|
||||
old_privkey = os.readlink(old_privkey)
|
||||
else:
|
||||
@@ -1135,9 +1138,16 @@ class RenewableCert(object):
|
||||
logger.debug("Writing symlink to old private key, %s.", old_privkey)
|
||||
os.symlink(old_privkey, target["privkey"])
|
||||
else:
|
||||
with open(target["privkey"], "wb") as f:
|
||||
with util.safe_open(target["privkey"], "wb", chmod=BASE_PRIVKEY_MODE) as f:
|
||||
logger.debug("Writing new private key to %s.", target["privkey"])
|
||||
f.write(new_privkey)
|
||||
# If the previous privkey in this lineage has an existing gid or group mode > 0,
|
||||
# let's keep those.
|
||||
group_mode = stat.S_IMODE(os.stat(old_privkey).st_mode) & \
|
||||
(stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)
|
||||
mode = BASE_PRIVKEY_MODE | group_mode
|
||||
os.chown(target["privkey"], -1, os.stat(old_privkey).st_gid)
|
||||
os.chmod(target["privkey"], mode)
|
||||
|
||||
# Save everything else
|
||||
with open(target["cert"], "wb") as f:
|
||||
|
||||
Reference in New Issue
Block a user