mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 22:08:07 -04:00
Merge branch 'master' into fix_771
Conflicts: letsencrypt/cli.py
This commit is contained in:
commit
395da0d7d5
24 changed files with 151 additions and 75 deletions
|
|
@ -32,7 +32,7 @@ RUN /opt/letsencrypt/src/ubuntu.sh && \
|
|||
# the above is not likely to change, so by putting it further up the
|
||||
# Dockerfile we make sure we cache as much as possible
|
||||
|
||||
COPY setup.py README.rst CHANGES.rst MANIFEST.in requirements.txt EULA linter_plugin.py tox.cover.sh tox.ini /opt/letsencrypt/src/
|
||||
COPY setup.py README.rst CHANGES.rst MANIFEST.in requirements.txt EULA linter_plugin.py tox.cover.sh tox.ini pep8.travis.sh .pep8 .pylintrc /opt/letsencrypt/src/
|
||||
|
||||
# all above files are necessary for setup.py, however, package source
|
||||
# code directory has to be copied separately to a subdirectory...
|
||||
|
|
@ -46,6 +46,8 @@ COPY letsencrypt /opt/letsencrypt/src/letsencrypt/
|
|||
COPY acme /opt/letsencrypt/src/acme/
|
||||
COPY letsencrypt-apache /opt/letsencrypt/src/letsencrypt-apache/
|
||||
COPY letsencrypt-nginx /opt/letsencrypt/src/letsencrypt-nginx/
|
||||
COPY letshelp-letsencrypt /opt/letsencrypt/src/letshelp-letsencrypt/
|
||||
COPY letsencrypt-compatibility-test /opt/letsencrypt/src/letsencrypt-compatibility-test/
|
||||
COPY tests /opt/letsencrypt/src/tests/
|
||||
|
||||
RUN virtualenv --no-site-packages -p python2 /opt/letsencrypt/venv && \
|
||||
|
|
@ -55,6 +57,8 @@ RUN virtualenv --no-site-packages -p python2 /opt/letsencrypt/venv && \
|
|||
-e /opt/letsencrypt/src \
|
||||
-e /opt/letsencrypt/src/letsencrypt-apache \
|
||||
-e /opt/letsencrypt/src/letsencrypt-nginx \
|
||||
-e /opt/letsencrypt/src/letshelp-letsencrypt \
|
||||
-e /opt/letsencrypt/src/letsencrypt-compatibility-test \
|
||||
-e /opt/letsencrypt/src[dev,docs,testing]
|
||||
|
||||
# install in editable mode (-e) to save space: it's not possible to
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
#!/bin/sh
|
||||
if ! hash brew 2>/dev/null; then
|
||||
echo "Homebrew Not Installed\nDownloading..."
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
fi
|
||||
|
||||
brew install augeas
|
||||
brew install dialog
|
||||
|
|
|
|||
|
|
@ -68,17 +68,16 @@ The following tools are there to help you:
|
|||
Integration
|
||||
~~~~~~~~~~~
|
||||
|
||||
First, install `Go`_ 1.5 (pick a value for GOPATH and put $GOPATH/bin in your
|
||||
PATH), libtool-ltdl, mariadb-server and rabbitmq-server and then start
|
||||
Boulder_, an ACME CA server::
|
||||
First, install `Go`_ 1.5, libtool-ltdl, mariadb-server and
|
||||
rabbitmq-server and then start Boulder_, an ACME CA server::
|
||||
|
||||
./tests/boulder-start.sh
|
||||
|
||||
The script will download, compile and run the executable; please be patient -
|
||||
it will take some time... Once its ready, you will see ``Server running,
|
||||
listening on 127.0.0.1:4000...``. Add the ``venv/bin/`` subdirectory of your
|
||||
letsencrypt repo to your path, and add an ``/etc/hosts`` entry pointing
|
||||
``le.wtf`` to 127.0.0.1. You may now run (in a separate terminal)::
|
||||
The script will download, compile and run the executable; please be
|
||||
patient - it will take some time... Once its ready, you will see
|
||||
``Server running, listening on 127.0.0.1:4000...``. Add an
|
||||
``/etc/hosts`` entry pointing ``le.wtf`` to 127.0.0.1. You may now
|
||||
run (in a separate terminal)::
|
||||
|
||||
./tests/boulder-integration.sh && echo OK || echo FAIL
|
||||
|
||||
|
|
@ -130,9 +129,8 @@ Docker
|
|||
|
||||
OSX users will probably find it easiest to set up a Docker container for
|
||||
development. Let's Encrypt comes with a Dockerfile (``Dockerfile-dev``)
|
||||
for doing so. To use Docker on OSX, install boot2docker using the
|
||||
instructions at https://docs.docker.com/installation/mac/ and start it
|
||||
from the command line (``boot2docker init``).
|
||||
for doing so. To use Docker on OSX, install and setup docker-machine using the
|
||||
instructions at https://docs.docker.com/installation/mac/.
|
||||
|
||||
To build the development Docker image::
|
||||
|
||||
|
|
|
|||
|
|
@ -241,6 +241,10 @@ class ApacheParser(object):
|
|||
Directives should be in the form of a case insensitive regex currently
|
||||
|
||||
.. todo:: arg should probably be a list
|
||||
.. todo:: arg search currently only supports direct matching. It does
|
||||
not handle the case of variables or quoted arguments. This should
|
||||
be adapted to use a generic search for the directive and then do a
|
||||
case-insensitive self.get_arg filter
|
||||
|
||||
Note: Augeas is inherently case sensitive while Apache is case
|
||||
insensitive. Augeas 1.0 allows case insensitive regexes like
|
||||
|
|
@ -315,6 +319,14 @@ class ApacheParser(object):
|
|||
|
||||
"""
|
||||
value = self.aug.get(match)
|
||||
|
||||
# No need to strip quotes for variables, as apache2ctl already does this
|
||||
# but we do need to strip quotes for all normal arguments.
|
||||
|
||||
# Note: normal argument may be a quoted variable
|
||||
# e.g. strip now, not later
|
||||
value = value.strip("'\"")
|
||||
|
||||
variables = ApacheParser.arg_var_interpreter.findall(value)
|
||||
|
||||
for var in variables:
|
||||
|
|
@ -390,10 +402,15 @@ class ApacheParser(object):
|
|||
# logger.error("Error: Invalid regexp characters in %s", arg)
|
||||
# return []
|
||||
|
||||
# Remove beginning and ending quotes
|
||||
arg = arg.strip("'\"")
|
||||
|
||||
# Standardize the include argument based on server root
|
||||
if not arg.startswith("/"):
|
||||
# Normpath will condense ../
|
||||
arg = os.path.normpath(os.path.join(self.root, arg))
|
||||
else:
|
||||
arg = os.path.normpath(arg)
|
||||
|
||||
# Attempts to add a transform to the file if one does not already exist
|
||||
if os.path.isdir(arg):
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class ComplexParserTest(util.ParserTest):
|
|||
"COMPLEX": "",
|
||||
"tls_port": "1234",
|
||||
"fnmatch_filename": "test_fnmatch.conf",
|
||||
"tls_port_str": "1234"
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -49,6 +50,12 @@ class ComplexParserTest(util.ParserTest):
|
|||
self.assertEqual(len(matches), 1)
|
||||
self.assertEqual(self.parser.get_arg(matches[0]), "1234")
|
||||
|
||||
def test_basic_variable_parsing_quotes(self):
|
||||
matches = self.parser.find_dir("TestVariablePortStr")
|
||||
|
||||
self.assertEqual(len(matches), 1)
|
||||
self.assertEqual(self.parser.get_arg(matches[0]), "1234")
|
||||
|
||||
def test_invalid_variable_parsing(self):
|
||||
del self.parser.variables["tls_port"]
|
||||
|
||||
|
|
@ -89,6 +96,7 @@ class ComplexParserTest(util.ParserTest):
|
|||
else:
|
||||
self.assertFalse(self.parser.find_dir("FNMATCH_DIRECTIVE"))
|
||||
|
||||
# NOTE: Only run one test per function otherwise you will have inf recursion
|
||||
def test_include(self):
|
||||
self.verify_fnmatch("test_fnmatch.?onf")
|
||||
|
||||
|
|
@ -98,6 +106,15 @@ class ComplexParserTest(util.ParserTest):
|
|||
def test_include_fullpath(self):
|
||||
self.verify_fnmatch(os.path.join(self.config_path, "test_fnmatch.conf"))
|
||||
|
||||
def test_include_fullpath_trailing_slash(self):
|
||||
self.verify_fnmatch(self.config_path + "//")
|
||||
|
||||
def test_include_single_quotes(self):
|
||||
self.verify_fnmatch("'" + self.config_path + "'")
|
||||
|
||||
def test_include_double_quotes(self):
|
||||
self.verify_fnmatch('"' + self.config_path + '"')
|
||||
|
||||
def test_include_variable(self):
|
||||
self.verify_fnmatch("../complex_parsing/${fnmatch_filename}")
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ IncludeOptional sites-enabled/*.conf
|
|||
Define COMPLEX
|
||||
|
||||
Define tls_port 1234
|
||||
Define tls_port_str "1234"
|
||||
|
||||
Define fnmatch_filename test_fnmatch.conf
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
TestVariablePort ${tls_port}
|
||||
TestVariablePortStr "${tls_port_str}"
|
||||
|
||||
LoadModule status_module modules/mod_status.so
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ def create_le_config(parent_dir):
|
|||
|
||||
def extract_configs(configs, parent_dir):
|
||||
"""Extracts configs to a new dir under parent_dir and returns it"""
|
||||
config_dir = os.path.join(parent_dir, "configs")
|
||||
config_dir = os.path.join(parent_dir, "renewal")
|
||||
|
||||
if os.path.isdir(configs):
|
||||
shutil.copytree(configs, config_dir, symlinks=True)
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@ import pkg_resources
|
|||
import unittest
|
||||
|
||||
import mock
|
||||
import zope.component
|
||||
|
||||
from acme import jose
|
||||
|
||||
from letsencrypt import configuration
|
||||
|
||||
from letsencrypt.tests import test_util
|
||||
|
||||
from letsencrypt.plugins import common
|
||||
|
|
@ -55,11 +58,17 @@ def get_nginx_configurator(
|
|||
backup_dir=backups,
|
||||
temp_checkpoint_dir=os.path.join(work_dir, "temp_checkpoints"),
|
||||
in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
|
||||
server="https://acme-server.org:443/new",
|
||||
dvsni_port=5001,
|
||||
),
|
||||
name="nginx",
|
||||
version=version)
|
||||
config.prepare()
|
||||
|
||||
# Provide general config utility.
|
||||
nsconfig = configuration.NamespaceConfig(config.config)
|
||||
zope.component.provideUtility(nsconfig)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -701,6 +701,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; only needed if your config is somewhere unsafe like /tmp/")
|
||||
|
||||
_paths_parser(helpful)
|
||||
# _plugins_parsing should be the last thing to act upon the main
|
||||
|
|
@ -884,14 +888,17 @@ def _handle_exception(exc_type, exc_value, trace, args):
|
|||
|
||||
if issubclass(exc_type, errors.Error):
|
||||
sys.exit(exc_value)
|
||||
elif args is None:
|
||||
sys.exit(
|
||||
"An unexpected error occurred. Please see the logfile '{0}' "
|
||||
"for more details.".format(logfile))
|
||||
else:
|
||||
sys.exit(
|
||||
"An unexpected error occurred. Please see the logfiles in {0} "
|
||||
"for more details.".format(args.logs_dir))
|
||||
# Tell the user a bit about what happened, without overwhelming
|
||||
# them with a full traceback
|
||||
msg = ("An unexpected error occurred.\n" +
|
||||
traceback.format_exception_only(exc_type, exc_value)[0] +
|
||||
"Please see the ")
|
||||
if args is None:
|
||||
msg += "logfile '{0}' for more details.".format(logfile)
|
||||
else:
|
||||
msg += "logfiles in {0} for more details.".format(args.logs_dir)
|
||||
sys.exit(msg)
|
||||
else:
|
||||
sys.exit("".join(
|
||||
traceback.format_exception(exc_type, exc_value, trace)))
|
||||
|
|
@ -906,15 +913,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)!
|
||||
|
|
|
|||
|
|
@ -313,7 +313,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
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ LIVE_DIR = "live"
|
|||
TEMP_CHECKPOINT_DIR = "temp_checkpoint"
|
||||
"""Temporary checkpoint directory (relative to `IConfig.work_dir`)."""
|
||||
|
||||
RENEWAL_CONFIGS_DIR = "configs"
|
||||
RENEWAL_CONFIGS_DIR = "renewal"
|
||||
"""Renewal configs directory, relative to `IConfig.config_dir`."""
|
||||
|
||||
RENEWER_CONFIG_FILENAME = "renewer.conf"
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ 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 interfaces
|
||||
from letsencrypt import le_util
|
||||
|
||||
|
||||
|
|
@ -45,8 +47,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 +77,10 @@ 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 %s" % (directory, uid, oct(mode)))
|
||||
else:
|
||||
raise
|
||||
|
||||
|
|
|
|||
|
|
@ -46,12 +46,9 @@ class ManualAuthenticatorTest(unittest.TestCase):
|
|||
self.assertEqual([], self.auth.perform([]))
|
||||
|
||||
@mock.patch("letsencrypt.plugins.manual.sys.stdout")
|
||||
@mock.patch("letsencrypt.plugins.manual.os.urandom")
|
||||
@mock.patch("acme.challenges.SimpleHTTPResponse.simple_verify")
|
||||
@mock.patch("__builtin__.raw_input")
|
||||
def test_perform(self, mock_raw_input, mock_verify, mock_urandom,
|
||||
mock_stdout):
|
||||
mock_urandom.side_effect = nonrandom_urandom
|
||||
def test_perform(self, mock_raw_input, mock_verify, mock_stdout):
|
||||
mock_verify.return_value = True
|
||||
|
||||
resp = challenges.SimpleHTTPResponse(tls=False)
|
||||
|
|
@ -61,27 +58,7 @@ class ManualAuthenticatorTest(unittest.TestCase):
|
|||
self.achalls[0].challb.chall, "foo.com", KEY.public_key(), 4430)
|
||||
|
||||
message = mock_stdout.write.mock_calls[0][1][0]
|
||||
self.assertEqual(message, """\
|
||||
Make sure your web server displays the following content at
|
||||
http://foo.com/.well-known/acme-challenge/ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ before continuing:
|
||||
|
||||
{"header": {"alg": "RS256", "jwk": {"e": "AQAB", "kty": "RSA", "n": "rHVztFHtH92ucFJD_N_HW9AsdRsUuHUBBBDlHwNlRd3fp580rv2-6QWE30cWgdmJS86ObRz6lUTor4R0T-3C5Q"}}, "payload": "eyJ0bHMiOiBmYWxzZSwgInRva2VuIjogIlpYWmhSM2htUVVSek5uQlRVbUl5VEVGMk9VbGFaakUzUkhRemFuVjRSMG9yVUVOME9USjNjaXR2UVEiLCAidHlwZSI6ICJzaW1wbGVIdHRwIn0", "signature": "jFPJFC-2eRyBw7Sl0wyEBhsdvRZtKk8hc6HykEPAiofZlIwdIu76u2xHqMVZWSZdpxwMNUnnawTEAqgMWFydMA"}
|
||||
|
||||
Content-Type header MUST be set to application/jose+json.
|
||||
|
||||
If you don\'t have HTTP server configured, you can run the following
|
||||
command on the target server (as root):
|
||||
|
||||
mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
|
||||
cd /tmp/letsencrypt/public_html
|
||||
echo -n \'{"header": {"alg": "RS256", "jwk": {"e": "AQAB", "kty": "RSA", "n": "rHVztFHtH92ucFJD_N_HW9AsdRsUuHUBBBDlHwNlRd3fp580rv2-6QWE30cWgdmJS86ObRz6lUTor4R0T-3C5Q"}}, "payload": "eyJ0bHMiOiBmYWxzZSwgInRva2VuIjogIlpYWmhSM2htUVVSek5uQlRVbUl5VEVGMk9VbGFaakUzUkhRemFuVjRSMG9yVUVOME9USjNjaXR2UVEiLCAidHlwZSI6ICJzaW1wbGVIdHRwIn0", "signature": "jFPJFC-2eRyBw7Sl0wyEBhsdvRZtKk8hc6HykEPAiofZlIwdIu76u2xHqMVZWSZdpxwMNUnnawTEAqgMWFydMA"}\' > .well-known/acme-challenge/ZXZhR3hmQURzNnBTUmIyTEF2OUlaZjE3RHQzanV4R0orUEN0OTJ3citvQQ
|
||||
# run only once per server:
|
||||
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \\
|
||||
"import BaseHTTPServer, SimpleHTTPServer; \\
|
||||
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {\'\': \'application/jose+json\'}; \\
|
||||
s = BaseHTTPServer.HTTPServer((\'\', 4430), SimpleHTTPServer.SimpleHTTPRequestHandler); \\
|
||||
s.serve_forever()" \n""")
|
||||
#self.assertTrue(validation in message)
|
||||
self.assertTrue(self.achalls[0].chall.encode("token") in message)
|
||||
|
||||
mock_verify.return_value = False
|
||||
self.assertEqual([None], self.auth.perform(self.achalls))
|
||||
|
|
@ -130,10 +107,5 @@ s.serve_forever()" \n""")
|
|||
mock_killpg.assert_called_once_with(1234, signal.SIGTERM)
|
||||
|
||||
|
||||
def nonrandom_urandom(num_bytes):
|
||||
"""Returns a string of length num_bytes"""
|
||||
return "x" * num_bytes
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ def renew(cert, old_version):
|
|||
# was an int, not a str)
|
||||
config.rsa_key_size = int(config.rsa_key_size)
|
||||
config.dvsni_port = int(config.dvsni_port)
|
||||
zope.component.provideUtility(config)
|
||||
try:
|
||||
authenticator = plugins[renewalparams["authenticator"]]
|
||||
except KeyError:
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -287,12 +288,12 @@ class Revoker(object):
|
|||
:class:`letsencrypt.revoker.Cert`
|
||||
|
||||
"""
|
||||
list_path2 = tempfile.mktemp(".tmp", "LIST")
|
||||
newfile_handle, list_path2 = tempfile.mkstemp(".tmp", "LIST")
|
||||
idx = 0
|
||||
|
||||
with open(self.list_path, "rb") as orgfile:
|
||||
csvreader = csv.reader(orgfile)
|
||||
with open(list_path2, "wb") as newfile:
|
||||
with os.fdopen(newfile_handle, "wb") as newfile:
|
||||
csvwriter = csv.writer(newfile)
|
||||
|
||||
for row in csvreader:
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ class BaseRenewableCertTest(unittest.TestCase):
|
|||
# TODO: maybe provide RenewerConfiguration.make_dirs?
|
||||
os.makedirs(os.path.join(self.tempdir, "live", "example.org"))
|
||||
os.makedirs(os.path.join(self.tempdir, "archive", "example.org"))
|
||||
os.makedirs(os.path.join(self.tempdir, "configs"))
|
||||
os.makedirs(os.path.join(self.tempdir, "renewal"))
|
||||
|
||||
config = configobj.ConfigObj()
|
||||
for kind in ALL_FOUR:
|
||||
config[kind] = os.path.join(self.tempdir, "live", "example.org",
|
||||
kind + ".pem")
|
||||
config.filename = os.path.join(self.tempdir, "configs",
|
||||
config.filename = os.path.join(self.tempdir, "renewal",
|
||||
"example.org.conf")
|
||||
self.config = config
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
. ./tests/integration/_common.sh
|
||||
export PATH="/usr/sbin:$PATH" # /usr/sbin/nginx
|
||||
|
||||
export GOPATH="${GOPATH:-/tmp/go}"
|
||||
export PATH="$GOPATH/bin:$PATH"
|
||||
|
||||
common() {
|
||||
letsencrypt_test \
|
||||
|
|
|
|||
|
|
@ -1,14 +1,36 @@
|
|||
#!/bin/sh -xe
|
||||
#!/bin/bash
|
||||
# Download and run Boulder instance for integration testing
|
||||
|
||||
|
||||
# ugh, go version output is like:
|
||||
# go version go1.4.2 linux/amd64
|
||||
GOVER=`go version | cut -d" " -f3 | cut -do -f2`
|
||||
|
||||
# version comparison
|
||||
function verlte {
|
||||
[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
|
||||
}
|
||||
|
||||
if ! verlte 1.5 "$GOVER" ; then
|
||||
echo "We require go version 1.5 or later; you have... $GOVER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -xe
|
||||
|
||||
export GOPATH="${GOPATH:-/tmp/go}"
|
||||
export PATH="$GOPATH/bin:$PATH"
|
||||
|
||||
# `/...` avoids `no buildable Go source files` errors, for more info
|
||||
# see `go help packages`
|
||||
go get -d github.com/letsencrypt/boulder/...
|
||||
cd $GOPATH/src/github.com/letsencrypt/boulder
|
||||
# goose is needed for ./test/create_db.sh
|
||||
go get bitbucket.org/liamstask/goose/cmd/goose
|
||||
if ! go get bitbucket.org/liamstask/goose/cmd/goose ; then
|
||||
echo Problems installing goose... perhaps rm -rf \$GOPATH \("$GOPATH"\)
|
||||
echo and try again...
|
||||
exit 1
|
||||
fi
|
||||
./test/create_db.sh
|
||||
./start.py &
|
||||
# Hopefully start.py bootstraps before integration test is started...
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ fi
|
|||
|
||||
cover () {
|
||||
if [ "$1" = "letsencrypt" ]; then
|
||||
min=96
|
||||
min=97
|
||||
elif [ "$1" = "acme" ]; then
|
||||
min=100
|
||||
elif [ "$1" = "letsencrypt_apache" ]; then
|
||||
min=100
|
||||
elif [ "$1" = "letsencrypt_nginx" ]; then
|
||||
min=96
|
||||
min=97
|
||||
elif [ "$1" = "letshelp_letsencrypt" ]; then
|
||||
min=100
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in a new issue