1
0
mirror of https://github.com/certbot/certbot.git synced 2026-01-26 07:41:33 +03:00

Merge remote-tracking branch 'origin/master' into faster-testfarm

This commit is contained in:
Peter Eckersley
2015-12-25 11:38:43 -08:00
37 changed files with 162 additions and 65 deletions

4
.gitignore vendored
View File

@@ -22,3 +22,7 @@ letsencrypt.log
# auth --cert-path --chain-path
/*.pem
# letstest
tests/letstest/letest-*/
tests/letstest/*.pem

View File

@@ -49,7 +49,6 @@ COPY letsencrypt-apache /opt/letsencrypt/src/letsencrypt-apache/
COPY letsencrypt-nginx /opt/letsencrypt/src/letsencrypt-nginx/
# py26reqs.txt not installed!
RUN virtualenv --no-site-packages -p python2 /opt/letsencrypt/venv && \
/opt/letsencrypt/venv/bin/pip install \
-e /opt/letsencrypt/src/acme \

View File

@@ -32,7 +32,6 @@ 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
# py26reqs.txt not installed!
COPY setup.py README.rst CHANGES.rst MANIFEST.in 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

View File

@@ -1,4 +1,3 @@
include py26reqs.txt
include README.rst
include CHANGES.rst
include CONTRIBUTING.md

View File

@@ -1,12 +1,12 @@
"""ACME protocol implementation.
This module is an implementation of the `ACME protocol`_. Latest
supported version: `v02`_.
supported version: `draft-ietf-acme-01`_.
.. _`ACME protocol`: https://github.com/letsencrypt/acme-spec
.. _`ACME protocol`: https://github.com/ietf-wg-acme/acme/
.. _`v02`:
https://github.com/letsencrypt/acme-spec/commit/d328fea2d507deb9822793c512830d827a4150c4
.. _`draft-ietf-acme-01`:
https://github.com/ietf-wg-acme/acme/tree/draft-ietf-acme-acme-01
"""

View File

@@ -10,8 +10,6 @@ install_requires = [
# load_pem_private/public_key (>=0.6)
# rsa_recover_prime_factors (>=0.8)
'cryptography>=0.8',
'ndg-httpsclient', # urllib3 InsecurePlatformWarning (#304)
'pyasn1', # urllib3 InsecurePlatformWarning (#304)
# Connection.set_tlsext_host_name (>=0.13), X509Req.get_extensions (>=0.15)
'PyOpenSSL>=0.15',
'pyrfc3339',
@@ -32,6 +30,11 @@ if sys.version_info < (2, 7):
else:
install_requires.append('mock')
if sys.version_info < (2, 7, 9):
# For secure SSL connexion with Python 2.7 (InsecurePlatformWarning)
install_requires.append('ndg-httpsclient')
install_requires.append('pyasn1')
docs_extras = [
'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags
'sphinx_rtd_theme',

View File

@@ -2,6 +2,5 @@ This directory contains scripts that install necessary OS-specific
prerequisite dependencies (see docs/using.rst).
General dependencies:
- git-core: py26reqs.txt git+https://*
- ca-certificates: communication with demo ACMO server at
https://www.letsencrypt-demo.org, py26reqs.txt git+https://*
https://www.letsencrypt-demo.org

View File

@@ -8,7 +8,6 @@
# ./bootstrap/dev/_common_venv.sh
deps="
git
python2
python-virtualenv
gcc

View File

@@ -24,26 +24,56 @@ apt-get update
# distro version (#346)
virtualenv=
if apt-cache show virtualenv > /dev/null ; then
if apt-cache show virtualenv > /dev/null 2>&1; then
virtualenv="virtualenv"
fi
if apt-cache show python-virtualenv > /dev/null ; then
if apt-cache show python-virtualenv > /dev/null 2>&1; then
virtualenv="$virtualenv python-virtualenv"
fi
augeas_pkg=libaugeas0
AUGVERSION=`apt-cache show --no-all-versions libaugeas0 | grep ^Version: | cut -d" " -f2`
if dpkg --compare-versions 1.0 gt "$AUGVERSION" ; then
if lsb_release -a | grep -q wheezy ; then
if ! grep -v -e ' *#' /etc/apt/sources.list | grep -q wheezy-backports ; then
# This can theoretically error if sources.list.d is empty, but in that case we don't care.
if ! grep -v -e ' *#' /etc/apt/sources.list.d/* 2>/dev/null | grep -q wheezy-backports ; then
/bin/echo -n "Installing augeas from wheezy-backports in 3 seconds..."
sleep 1s
/bin/echo -ne "\e[0K\rInstalling augeas from wheezy-backports in 2 seconds..."
sleep 1s
/bin/echo -e "\e[0K\rInstalling augeas from wheezy-backports in 1 second ..."
sleep 1s
/bin/echo '(Backports are only installed if explicitly requested via "apt-get install -t wheezy-backports")'
echo deb http://http.debian.net/debian wheezy-backports main >> /etc/apt/sources.list.d/wheezy-backports.list
apt-get update
fi
fi
apt-get install -y --no-install-recommends -t wheezy-backports libaugeas0
augeas_pkg=
else
echo "No libaugeas0 version is available that's new enough to run the"
echo "Let's Encrypt apache plugin..."
fi
# XXX add a case for ubuntu PPAs
fi
apt-get install -y --no-install-recommends \
git \
python \
python-dev \
$virtualenv \
gcc \
dialog \
libaugeas0 \
$augeas_pkg \
libssl-dev \
libffi-dev \
ca-certificates \
if ! command -v virtualenv > /dev/null ; then
echo Failed to install a working \"virtualenv\" command, exiting
exit 1

View File

@@ -1,6 +1,6 @@
#!/bin/sh
PACKAGES="dev-vcs/git
PACKAGES="
dev-lang/python:2.7
dev-python/virtualenv
dev-util/dialog

View File

@@ -33,9 +33,7 @@ then
fi
fi
# "git-core" seems to be an alias for "git" in CentOS 7 (yum search fails)
if ! $tool install -y \
git-core \
gcc \
dialog \
augeas-libs \

View File

@@ -2,7 +2,7 @@
# SLE12 don't have python-virtualenv
zypper -nq in -l git-core \
zypper -nq in -l \
python \
python-devel \
python-virtualenv \

View File

@@ -4,7 +4,6 @@
export VENV_ARGS="--python python2"
./bootstrap/dev/_venv_common.sh \
-r py26reqs.txt \
-e acme[testing] \
-e .[dev,docs,testing] \
-e letsencrypt-apache \

View File

@@ -1,7 +1,6 @@
#!/bin/sh -xe
pkg install -Ay \
git \
python \
py27-virtualenv \
augeas \

View File

@@ -20,7 +20,7 @@ fi
pip install -U setuptools
pip install -U pip
pip install -U -r py26reqs.txt letsencrypt letsencrypt-apache # letsencrypt-nginx
pip install -U letsencrypt letsencrypt-apache # letsencrypt-nginx
echo
echo "Congratulations, Let's Encrypt has been successfully installed/updated!"

View File

@@ -371,7 +371,7 @@ If you run Debian Stretch or Debian Sid, you can install letsencrypt packages.
sudo apt-get update
sudo apt-get install letsencrypt python-letsencrypt-apache
If you don't want to use the Apache plugin, you can ommit the
If you don't want to use the Apache plugin, you can omit the
``python-letsencrypt-apache`` package.
Packages for Debian Jessie are coming in the next few weeks.

View File

@@ -542,7 +542,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
if "ssl_module" not in self.parser.modules:
self.enable_mod("ssl", temp=temp)
if self.version >= (2, 4) and "socache_shmcb_module" not in self.parser.modules:
self.enable_mod("socache_shmcb", temp=temp)
# Check for Listen <port>
# Note: This could be made to also look for ip:443 combo
listens = [self.parser.get_arg(x).split()[0] for x in self.parser.find_dir("Listen")]
@@ -1271,6 +1272,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
self.config_test()
logger.debug(self.reverter.view_config_changes())
self._reload()
def _reload(self):
@@ -1399,7 +1401,7 @@ def _get_mod_deps(mod_name):
"""
deps = {
"ssl": ["setenvif", "mime", "socache_shmcb"]
"ssl": ["setenvif", "mime"]
}
return deps.get(mod_name, [])

View File

@@ -33,7 +33,7 @@ REWRITE_HTTPS_ARGS_WITH_END = [
https vhost"""
HSTS_ARGS = ["always", "set", "Strict-Transport-Security",
"\"max-age=31536000; includeSubDomains\""]
"\"max-age=31536000\""]
"""Apache header arguments for HSTS"""
UIR_ARGS = ["always", "set", "Content-Security-Policy",

View File

@@ -19,7 +19,6 @@ class ApacheParser(object):
:ivar str root: Normalized absolute path to the server root
directory. Without trailing slash.
:ivar str root: Server root
:ivar set modules: All module names that are currently enabled.
:ivar dict loc: Location to place directives, root - configuration origin,
default - user config file, name - NameVirtualHost,
@@ -36,6 +35,7 @@ class ApacheParser(object):
# https://httpd.apache.org/docs/2.4/mod/core.html#ifdefine
# This only handles invocation parameters and Define directives!
self.variables = {}
self.unparsable = False
self.update_runtime_variables(ctl)
self.aug = aug
@@ -60,6 +60,11 @@ class ApacheParser(object):
# Sites-available is not included naturally in configuration
self._parse_file(os.path.join(self.root, "sites-available") + "/*")
#check to see if there were unparsed define statements
if self.unparsable:
if self.find_dir("Define", exclude=False):
raise errors.PluginError("Error parsing runtime variables")
def init_modules(self):
"""Iterates on the configuration until no new modules are loaded.
@@ -101,7 +106,8 @@ class ApacheParser(object):
try:
matches.remove("DUMP_RUN_CFG")
except ValueError:
raise errors.PluginError("Unable to parse runtime variables")
self.unparsable = True
return
for match in matches:
if match.count("=") > 1:

View File

@@ -28,10 +28,21 @@ class TwoVhost80Test(util.ApacheTest):
self.config = util.get_apache_configurator(
self.config_path, self.config_dir, self.work_dir)
self.config = self.mock_deploy_cert(self.config)
self.vh_truth = util.get_vh_truth(
self.temp_dir, "debian_apache_2_4/two_vhost_80")
def mock_deploy_cert(self, config):
"""A test for a mock deploy cert"""
self.config.real_deploy_cert = self.config.deploy_cert
def mocked_deploy_cert(*args, **kwargs):
"""a helper to mock a deployed cert"""
with mock.patch(
"letsencrypt_apache.configurator.ApacheConfigurator.enable_mod"):
config.real_deploy_cert(*args, **kwargs)
self.config.deploy_cert = mocked_deploy_cert
return self.config
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
@@ -251,6 +262,7 @@ class TwoVhost80Test(util.ApacheTest):
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.config = self.mock_deploy_cert(self.config)
self.config.deploy_cert(
"random.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
@@ -277,6 +289,7 @@ class TwoVhost80Test(util.ApacheTest):
def test_deploy_cert_newssl_no_fullchain(self):
self.config = util.get_apache_configurator(
self.config_path, self.config_dir, self.work_dir, version=(2, 4, 16))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
@@ -290,6 +303,7 @@ class TwoVhost80Test(util.ApacheTest):
def test_deploy_cert_old_apache_no_chain(self):
self.config = util.get_apache_configurator(
self.config_path, self.config_dir, self.work_dir, version=(2, 4, 7))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")

View File

@@ -151,8 +151,8 @@ class BasicParserTest(util.ParserTest):
@mock.patch("letsencrypt_apache.parser.ApacheParser._get_runtime_cfg")
def test_update_runtime_vars_bad_output(self, mock_cfg):
mock_cfg.return_value = "Define: TLS=443=24"
self.assertRaises(
errors.PluginError, self.parser.update_runtime_variables, "ctl")
self.parser.update_runtime_variables("ctl")
self.assertTrue(self.parser.unparsable)
mock_cfg.return_value = "Define: DUMP_RUN_CFG\nDefine: TLS=443=24"
self.assertRaises(
@@ -185,6 +185,21 @@ class ParserInitTest(util.ApacheTest):
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
@mock.patch("letsencrypt_apache.parser.ApacheParser._get_runtime_cfg")
def test_unparsable(self, mock_cfg):
from letsencrypt_apache.parser import ApacheParser
def unparsable_true(self, arg):
"""a helper to set the self unparsabale to true"""
print "side effect has passed in arg: %s", arg
self.unparsable = True
with mock.patch.object(ApacheParser, 'update_runtime_variables', autospec=True) as urv:
urv.side_effect = unparsable_true
mock_cfg.return_value = ('Define: TEST')
self.assertRaises(
errors.PluginError,
ApacheParser, self.aug, os.path.relpath(self.config_path), "ctl")
self.assertEquals(1, 1)
def test_root_normalized(self):
from letsencrypt_apache.parser import ApacheParser

View File

@@ -78,7 +78,9 @@ class TlsSniPerformTest(util.ApacheTest):
# pylint: disable=protected-access
self.sni._setup_challenge_cert = mock_setup_cert
sni_responses = self.sni.perform()
with mock.patch(
"letsencrypt_apache.configurator.ApacheConfigurator.enable_mod"):
sni_responses = self.sni.perform()
self.assertEqual(mock_setup_cert.call_count, 2)

View File

@@ -1,12 +1,14 @@
"""A class that performs TLS-SNI-01 challenges for Apache"""
import os
import logging
from letsencrypt.plugins import common
from letsencrypt_apache import obj
from letsencrypt_apache import parser
logger = logging.getLogger(__name__)
class ApacheTlsSni01(common.TLSSNI01):
"""Class that performs TLS-SNI-01 challenges within the Apache configurator
@@ -104,6 +106,7 @@ class ApacheTlsSni01(common.TLSSNI01):
self.configurator.reverter.register_file_creation(
True, self.challenge_conf)
logger.debug("writing a config file with text: %s", config_text)
with open(self.challenge_conf, "w") as new_conf:
new_conf.write(config_text)

View File

@@ -47,13 +47,13 @@ if test "`id -u`" -ne "0" ; then
args=""
# This `while` loop iterates over all parameters given to this function.
# For each parameter, all `'` will be replace by `'"'"'`, and the escaped string
# will be wrap in a pair of `'`, then append to `$args` string
# will be wrapped in a pair of `'`, then appended to `$args` string
# For example, `echo "It's only 1\$\!"` will be escaped to:
# 'echo' 'It'"'"'s only 1$!'
# │ │└┼┘│
# │ │ │ └── `'s only 1$!'` the literal string
# │ │ └── `\"'\"` is a single quote (as a string)
# │ └── `'It'`, to be concatenated with the strings followed it
# │ └── `'It'`, to be concatenated with the strings following it
# └── `echo` wrapped in a pair of `'`, it's totally fine for the shell command itself
while [ $# -ne 0 ]; do
args="$args'$(printf "%s" "$1" | sed -e "s/'/'\"'\"'/g")' "
@@ -176,7 +176,7 @@ if [ "$VERBOSE" = 1 ] ; then
echo
$VENV_BIN/pip install -U setuptools
$VENV_BIN/pip install -U pip
$VENV_BIN/pip install -r "$LEA_PATH"/py26reqs.txt -U letsencrypt letsencrypt-apache
$VENV_BIN/pip install -U letsencrypt letsencrypt-apache
# nginx is buggy / disabled for now, but upgrade it if the user has
# installed it manually
if $VENV_BIN/pip freeze | grep -q letsencrypt-nginx ; then
@@ -188,8 +188,6 @@ else
$VENV_BIN/pip install -U pip > /dev/null
printf .
# nginx is buggy / disabled for now...
$VENV_BIN/pip install -r "$LEA_PATH"/py26reqs.txt > /dev/null
printf .
$VENV_BIN/pip install -U letsencrypt > /dev/null
printf .
$VENV_BIN/pip install -U letsencrypt-apache > /dev/null
@@ -202,5 +200,5 @@ fi
# Explain what's about to happen, for the benefit of those getting sudo
# password prompts...
echo "Running with virtualenv:" $SUDO $VENV_BIN/letsencrypt "$@"
echo "Requesting root privileges to run with virtualenv:" $SUDO $VENV_BIN/letsencrypt "$@"
$SUDO $VENV_BIN/letsencrypt "$@"

View File

@@ -15,11 +15,12 @@ from acme import crypto_util
from acme import messages
from letsencrypt import achallenges
from letsencrypt import errors as le_errors
from letsencrypt import validator
from letsencrypt.tests import acme_util
from letsencrypt_compatibility_test import errors
from letsencrypt_compatibility_test import util
from letsencrypt_compatibility_test import validator
from letsencrypt_compatibility_test.configurators.apache import apache24

View File

@@ -1,4 +1,4 @@
"""Tests for letsencrypt.validator."""
"""Tests for letsencrypt_compatibility_test.validator."""
import requests
import unittest
@@ -6,28 +6,31 @@ import mock
import OpenSSL
from acme import errors as acme_errors
from letsencrypt import validator
from letsencrypt_compatibility_test import validator
class ValidatorTest(unittest.TestCase):
def setUp(self):
self.validator = validator.Validator()
@mock.patch("letsencrypt.validator.crypto_util.probe_sni")
@mock.patch(
"letsencrypt_compatibility_test.validator.crypto_util.probe_sni")
def test_certificate_success(self, mock_probe_sni):
cert = OpenSSL.crypto.X509()
mock_probe_sni.return_value = cert
self.assertTrue(self.validator.certificate(
cert, "test.com", "127.0.0.1"))
@mock.patch("letsencrypt.validator.crypto_util.probe_sni")
@mock.patch(
"letsencrypt_compatibility_test.validator.crypto_util.probe_sni")
def test_certificate_error(self, mock_probe_sni):
cert = OpenSSL.crypto.X509()
mock_probe_sni.side_effect = [acme_errors.Error]
self.assertFalse(self.validator.certificate(
cert, "test.com", "127.0.0.1"))
@mock.patch("letsencrypt.validator.crypto_util.probe_sni")
@mock.patch(
"letsencrypt_compatibility_test.validator.crypto_util.probe_sni")
def test_certificate_failure(self, mock_probe_sni):
cert = OpenSSL.crypto.X509()
cert.set_serial_number(1337)
@@ -35,67 +38,67 @@ class ValidatorTest(unittest.TestCase):
self.assertFalse(self.validator.certificate(
cert, "test.com", "127.0.0.1"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_succesful_redirect(self, mock_get_request):
mock_get_request.return_value = create_response(
301, {"location": "https://test.com"})
self.assertTrue(self.validator.redirect("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_redirect_with_headers(self, mock_get_request):
mock_get_request.return_value = create_response(
301, {"location": "https://test.com"})
self.assertTrue(self.validator.redirect(
"test.com", headers={"Host": "test.com"}))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_redirect_missing_location(self, mock_get_request):
mock_get_request.return_value = create_response(301)
self.assertFalse(self.validator.redirect("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_redirect_wrong_status_code(self, mock_get_request):
mock_get_request.return_value = create_response(
201, {"location": "https://test.com"})
self.assertFalse(self.validator.redirect("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_redirect_wrong_redirect_code(self, mock_get_request):
mock_get_request.return_value = create_response(
303, {"location": "https://test.com"})
self.assertFalse(self.validator.redirect("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts_empty(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security": ""})
self.assertFalse(self.validator.hsts("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts_malformed(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security": "sdfal"})
self.assertFalse(self.validator.hsts("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts_bad_max_age(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security": "max-age=not-an-int"})
self.assertFalse(self.validator.hsts("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts_expire(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security": "max-age=3600"})
self.assertFalse(self.validator.hsts("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security": "max-age=31536000"})
self.assertTrue(self.validator.hsts("test.com"))
@mock.patch("letsencrypt.validator.requests.get")
@mock.patch("letsencrypt_compatibility_test.validator.requests.get")
def test_hsts_include_subdomains(self, mock_get_request):
mock_get_request.return_value = create_response(
headers={"strict-transport-security":

View File

@@ -10,6 +10,7 @@ install_requires = [
'letsencrypt=={0}'.format(version),
'letsencrypt-apache=={0}'.format(version),
'docker-py',
'requests',
'zope.interface',
]
@@ -18,6 +19,11 @@ if sys.version_info < (2, 7):
else:
install_requires.append('mock')
if sys.version_info < (2, 7, 9):
# For secure SSL connexion with Python 2.7 (InsecurePlatformWarning)
install_requires.append('ndg-httpsclient')
install_requires.append('pyasn1')
docs_extras = [
'repoze.sphinx.autointerface',
'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags

View File

@@ -1189,7 +1189,7 @@ def _plugins_parsing(helpful, plugins):
# These would normally be a flag within the webroot plugin, but because
# they are parsed in conjunction with --domains, they live here for
# legibiility. helpful.add_plugin_ags must be called first to add the
# legibility. helpful.add_plugin_ags must be called first to add the
# "webroot" topic
helpful.add("webroot", "-w", "--webroot-path", action=WebrootPathProcessor,
help="public_html / webroot path. This can be specified multiple times to "

View File

@@ -66,8 +66,16 @@ class AuthenticatorTest(unittest.TestCase):
def test_prepare_reraises_other_errors(self):
self.auth.full_path = os.path.join(self.path, "null")
permission_canary = os.path.join(self.path, "rnd")
with open(permission_canary, "w") as f:
f.write("thingimy")
os.chmod(self.path, 0o000)
self.assertRaises(errors.PluginError, self.auth.prepare)
try:
open(permission_canary, "r")
print "Warning, running tests as root skips permissions tests..."
except IOError:
# ok, permissions work, test away...
self.assertRaises(errors.PluginError, self.auth.prepare)
os.chmod(self.path, 0o700)
@mock.patch("letsencrypt.plugins.webroot.os.chown")

View File

@@ -116,6 +116,7 @@ def renew(cert, old_version):
def _cli_log_handler(args, level, fmt): # pylint: disable=unused-argument
handler = colored_logging.StreamHandler()
handler.setFormatter(logging.Formatter(fmt))
handler.setLevel(level)
return handler

View File

@@ -450,12 +450,15 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
:param int version: the desired version number
:returns: the subject names
:rtype: `list` of `str`
:raises .CertStorageError: if could not find cert file.
"""
if version is None:
target = self.current_target("cert")
else:
target = self.version("cert", version)
if target is None:
raise errors.CertStorageError("could not find cert file")
with open(target) as f:
return crypto_util.get_sans_from_cert(f.read())

View File

@@ -1,2 +0,0 @@
# https://github.com/bw2/ConfigArgParse/issues/17
git+https://github.com/kuba/ConfigArgParse.git@python2.6-0.9.3#egg=ConfigArgParse

View File

@@ -32,7 +32,6 @@ version = meta['version']
install_requires = [
'acme=={0}'.format(version),
'ConfigArgParse',
'configobj',
'cryptography>=0.7', # load_pem_x509_certificate
'parsedatetime',
@@ -41,7 +40,6 @@ install_requires = [
'pyrfc3339',
'python2-pythondialog>=3.2.2rc1', # Debian squeeze support, cf. #280
'pytz',
'requests',
'setuptools', # pkg_resources
'six',
'zope.component',
@@ -53,10 +51,14 @@ if sys.version_info < (2, 7):
install_requires.extend([
# only some distros recognize stdlib argparse as already satisfying
'argparse',
'ConfigArgParse>=0.10.0', # python2.6 support, upstream #17
'mock<1.1.0',
])
else:
install_requires.append('mock')
install_requires.extend([
'ConfigArgParse',
'mock',
])
dev_extras = [
# Pin astroid==1.3.5, pylint==1.4.2 as a workaround for #289

View File

@@ -0,0 +1,7 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^.*(,|;|:|<|>|">|"<|/|\\\.\.\\).* [NC,OR]
RewriteCond %{REQUEST_URI} ^.*(\=|\@|\[|\]|\^|\`|\{|\}|\~).* [NC,OR]
RewriteCond %{REQUEST_URI} ^.*(\'|%0A|%0D|%27|%3C|%3E|%00).* [NC]
RewriteRule ^(.*)$ - [F,L]
</IfModule>

View File

@@ -86,7 +86,7 @@ SetVersion() {
done
sed -i "s/^__version.*/__version__ = '$ver'/" letsencrypt/__init__.py
git add -p $SUBPKGS # interactive user input
git add -p letsencrypt $SUBPKGS # interactive user input
}
SetVersion "$version"
git commit --gpg-sign="$RELEASE_GPG_KEY" -m "Release $version"

View File

@@ -17,7 +17,7 @@ envlist = py26,py27,py33,py34,py35,cover,lint
commands =
pip install -e acme[testing]
nosetests -v acme
pip install -r py26reqs.txt -e .[testing]
pip install -e .[testing]
nosetests -v letsencrypt
pip install -e letsencrypt-apache
nosetests -v letsencrypt_apache