Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/certbot/certbot.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'letsencrypt/plugins/webroot.py')
-rw-r--r--letsencrypt/plugins/webroot.py59
1 files changed, 36 insertions, 23 deletions
diff --git a/letsencrypt/plugins/webroot.py b/letsencrypt/plugins/webroot.py
index 0b81d45b5..0679bc349 100644
--- a/letsencrypt/plugins/webroot.py
+++ b/letsencrypt/plugins/webroot.py
@@ -2,7 +2,6 @@
import errno
import logging
import os
-import stat
import zope.interface
@@ -59,24 +58,38 @@ to serve all files under specified web root ({0})."""
logger.debug("Creating root challenges validation dir at %s",
self.full_roots[name])
+
+ # Change the permissions to be writable (GH #1389)
+ # Umask is used instead of chmod to ensure the client can also
+ # run as non-root (GH #1795)
+ old_umask = os.umask(0o022)
+
try:
- os.makedirs(self.full_roots[name])
- # Set permissions as parent directory (GH #1389)
- # We don't use the parameters in makedirs because it
- # may not always work
+ # This is coupled with the "umask" call above because
+ # os.makedirs's "mode" parameter may not always work:
# https://stackoverflow.com/questions/5231901/permission-problems-when-creating-a-dir-with-os-makedirs-python
- stat_path = os.stat(path)
- filemode = stat.S_IMODE(stat_path.st_mode)
- os.chmod(self.full_roots[name], filemode)
- # Set owner and group, too
- os.chown(self.full_roots[name], stat_path.st_uid,
- stat_path.st_gid)
+ os.makedirs(self.full_roots[name], 0o0755)
+
+ # Set owner as parent directory if possible
+ try:
+ stat_path = os.stat(path)
+ os.chown(self.full_roots[name], stat_path.st_uid,
+ stat_path.st_gid)
+ except OSError as exception:
+ if exception.errno == errno.EACCES:
+ logger.debug("Insufficient permissions to change owner and uid - ignoring")
+ else:
+ raise errors.PluginError(
+ "Couldn't create root for {0} http-01 "
+ "challenge responses: {1}", name, exception)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise errors.PluginError(
"Couldn't create root for {0} http-01 "
"challenge responses: {1}", name, exception)
+ finally:
+ os.umask(old_umask)
def perform(self, achalls): # pylint: disable=missing-docstring
assert self.full_roots, "Webroot plugin appears to be missing webroot map"
@@ -87,26 +100,26 @@ to serve all files under specified web root ({0})."""
path = self.full_roots[achall.domain]
except IndexError:
raise errors.PluginError("Missing --webroot-path for domain: {1}"
- .format(achall.domain))
+ .format(achall.domain))
if not os.path.exists(path):
raise errors.PluginError("Mysteriously missing path {0} for domain: {1}"
- .format(path, achall.domain))
+ .format(path, achall.domain))
return os.path.join(path, achall.chall.encode("token"))
def _perform_single(self, achall):
response, validation = achall.response_and_validation()
+
path = self._path_for_achall(achall)
logger.debug("Attempting to save validation to %s", path)
- with open(path, "w") as validation_file:
- validation_file.write(validation.encode())
-
- # Set permissions as parent directory (GH #1389)
- parent_path = self.full_roots[achall.domain]
- stat_parent_path = os.stat(parent_path)
- filemode = stat.S_IMODE(stat_parent_path.st_mode)
- # Remove execution bit (not needed for this file)
- os.chmod(path, filemode & ~stat.S_IEXEC)
- os.chown(path, stat_parent_path.st_uid, stat_parent_path.st_gid)
+
+ # Change permissions to be world-readable, owner-writable (GH #1795)
+ old_umask = os.umask(0o022)
+
+ try:
+ with open(path, "w") as validation_file:
+ validation_file.write(validation.encode())
+ finally:
+ os.umask(old_umask)
return response