Skip to content

Commit

Permalink
Merge pull request certbot#1597 from lbeltrame/fix-webroot-permissions
Browse files Browse the repository at this point in the history
Fix webroot permissions [mergeable, but enhancements also requested]
  • Loading branch information
pde committed Dec 2, 2015
2 parents f4dd660 + 2a5f539 commit a191daf
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
21 changes: 21 additions & 0 deletions letsencrypt/plugins/webroot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import errno
import logging
import os
import stat

import zope.interface

Expand Down Expand Up @@ -60,6 +61,17 @@ def prepare(self): # pylint: disable=missing-docstring
self.full_roots[name])
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
# 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)

except OSError as exception:
if exception.errno != errno.EEXIST:
raise errors.PluginError(
Expand Down Expand Up @@ -87,6 +99,15 @@ def _perform_single(self, 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)

return response

def cleanup(self, achalls): # pylint: disable=missing-docstring
Expand Down
18 changes: 18 additions & 0 deletions letsencrypt/plugins/webroot_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import shutil
import tempfile
import unittest
import stat

import mock

Expand Down Expand Up @@ -69,6 +70,23 @@ def test_prepare_reraises_other_errors(self):
self.assertRaises(errors.PluginError, self.auth.prepare)
os.chmod(self.path, 0o700)

def test_prepare_permissions(self):

# Remove exec bit from permission check, so that it
# matches the file
responses = self.auth.perform([self.achall])
parent_permissions = (stat.S_IMODE(os.stat(self.path).st_mode) &
~stat.S_IEXEC)

actual_permissions = stat.S_IMODE(os.stat(self.validation_path).st_mode)

self.assertEqual(parent_permissions, actual_permissions)
parent_gid = os.stat(self.path).st_gid
parent_uid = os.stat(self.path).st_uid

self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid)
self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid)

def test_perform_cleanup(self):
responses = self.auth.perform([self.achall])
self.assertEqual(1, len(responses))
Expand Down

0 comments on commit a191daf

Please sign in to comment.