Merge branch 'master' into update_registration

This commit is contained in:
Brad Warren
2016-05-31 14:35:30 -07:00
56 changed files with 539 additions and 364 deletions
+1 -1
View File
@@ -500,7 +500,7 @@ class DNS(_TokenChallenge):
""" """
return DNSResponse(validation=self.gen_validation( return DNSResponse(validation=self.gen_validation(
self, account_key, **kwargs)) account_key, **kwargs))
def validation_domain_name(self, name): def validation_domain_name(self, name):
"""Domain name for TXT validation record. """Domain name for TXT validation record.
+1 -1
View File
@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.7.0.dev0' version = '0.8.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
+9 -10
View File
@@ -15,7 +15,7 @@ from acme import challenges
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot.plugins import common from certbot.plugins import common
@@ -106,8 +106,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
add("handle-sites", default=constants.os_constant("handle_sites"), add("handle-sites", default=constants.os_constant("handle_sites"),
help="Let installer handle enabling sites for you." + help="Let installer handle enabling sites for you." +
"(Only Ubuntu/Debian currently)") "(Only Ubuntu/Debian currently)")
le_util.add_deprecated_argument(add, argument_name="ctl", nargs=1) util.add_deprecated_argument(add, argument_name="ctl", nargs=1)
le_util.add_deprecated_argument( util.add_deprecated_argument(
add, argument_name="init-script", nargs=1) add, argument_name="init-script", nargs=1)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -151,7 +151,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
""" """
# Verify Apache is installed # Verify Apache is installed
if not le_util.exe_exists(constants.os_constant("restart_cmd")[0]): if not util.exe_exists(constants.os_constant("restart_cmd")[0]):
raise errors.NoInstallationError raise errors.NoInstallationError
# Make sure configuration is valid # Make sure configuration is valid
@@ -1521,14 +1521,14 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# Generate reversal command. # Generate reversal command.
# Try to be safe here... check that we can probably reverse before # Try to be safe here... check that we can probably reverse before
# applying enmod command # applying enmod command
if not le_util.exe_exists(self.conf("dismod")): if not util.exe_exists(self.conf("dismod")):
raise errors.MisconfigurationError( raise errors.MisconfigurationError(
"Unable to find a2dismod, please make sure a2enmod and " "Unable to find a2dismod, please make sure a2enmod and "
"a2dismod are configured correctly for certbot.") "a2dismod are configured correctly for certbot.")
self.reverter.register_undo_command( self.reverter.register_undo_command(
temp, [self.conf("dismod"), mod_name]) temp, [self.conf("dismod"), mod_name])
le_util.run_script([self.conf("enmod"), mod_name]) util.run_script([self.conf("enmod"), mod_name])
def restart(self): def restart(self):
"""Runs a config test and reloads the Apache server. """Runs a config test and reloads the Apache server.
@@ -1547,7 +1547,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
""" """
try: try:
le_util.run_script(constants.os_constant("restart_cmd")) util.run_script(constants.os_constant("restart_cmd"))
except errors.SubprocessError as err: except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err)) raise errors.MisconfigurationError(str(err))
@@ -1558,7 +1558,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
""" """
try: try:
le_util.run_script(constants.os_constant("conftest_cmd")) util.run_script(constants.os_constant("conftest_cmd"))
except errors.SubprocessError as err: except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err)) raise errors.MisconfigurationError(str(err))
@@ -1574,8 +1574,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
""" """
try: try:
stdout, _ = le_util.run_script( stdout, _ = util.run_script(constants.os_constant("version_cmd"))
constants.os_constant("version_cmd"))
except errors.SubprocessError: except errors.SubprocessError:
raise errors.PluginError( raise errors.PluginError(
"Unable to run %s -v" % "Unable to run %s -v" %
+4 -2
View File
@@ -1,6 +1,6 @@
"""Apache plugin constants.""" """Apache plugin constants."""
import pkg_resources import pkg_resources
from certbot import le_util from certbot import util
CLI_DEFAULTS_DEBIAN = dict( CLI_DEFAULTS_DEBIAN = dict(
@@ -78,6 +78,8 @@ CLI_DEFAULTS = {
"centos linux": CLI_DEFAULTS_CENTOS, "centos linux": CLI_DEFAULTS_CENTOS,
"fedora": CLI_DEFAULTS_CENTOS, "fedora": CLI_DEFAULTS_CENTOS,
"red hat enterprise linux server": CLI_DEFAULTS_CENTOS, "red hat enterprise linux server": CLI_DEFAULTS_CENTOS,
"rhel": CLI_DEFAULTS_CENTOS,
"amazon": CLI_DEFAULTS_CENTOS,
"gentoo base system": CLI_DEFAULTS_GENTOO, "gentoo base system": CLI_DEFAULTS_GENTOO,
"darwin": CLI_DEFAULTS_DARWIN, "darwin": CLI_DEFAULTS_DARWIN,
} }
@@ -116,7 +118,7 @@ def os_constant(key):
:param key: name of cli constant :param key: name of cli constant
:return: value of constant for active os :return: value of constant for active os
""" """
os_info = le_util.get_os_info() os_info = util.get_os_info()
try: try:
constants = CLI_DEFAULTS[os_info[0].lower()] constants = CLI_DEFAULTS[os_info[0].lower()]
except KeyError: except KeyError:
@@ -49,14 +49,14 @@ class MultipleVhostsTest(util.ApacheTest):
shutil.rmtree(self.config_dir) shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir) shutil.rmtree(self.work_dir)
@mock.patch("certbot_apache.configurator.le_util.exe_exists") @mock.patch("certbot_apache.configurator.util.exe_exists")
def test_prepare_no_install(self, mock_exe_exists): def test_prepare_no_install(self, mock_exe_exists):
mock_exe_exists.return_value = False mock_exe_exists.return_value = False
self.assertRaises( self.assertRaises(
errors.NoInstallationError, self.config.prepare) errors.NoInstallationError, self.config.prepare)
@mock.patch("certbot_apache.parser.ApacheParser") @mock.patch("certbot_apache.parser.ApacheParser")
@mock.patch("certbot_apache.configurator.le_util.exe_exists") @mock.patch("certbot_apache.configurator.util.exe_exists")
def test_prepare_version(self, mock_exe_exists, _): def test_prepare_version(self, mock_exe_exists, _):
mock_exe_exists.return_value = True mock_exe_exists.return_value = True
self.config.version = None self.config.version = None
@@ -67,7 +67,7 @@ class MultipleVhostsTest(util.ApacheTest):
errors.NotSupportedError, self.config.prepare) errors.NotSupportedError, self.config.prepare)
@mock.patch("certbot_apache.parser.ApacheParser") @mock.patch("certbot_apache.parser.ApacheParser")
@mock.patch("certbot_apache.configurator.le_util.exe_exists") @mock.patch("certbot_apache.configurator.util.exe_exists")
def test_prepare_old_aug(self, mock_exe_exists, _): def test_prepare_old_aug(self, mock_exe_exists, _):
mock_exe_exists.return_value = True mock_exe_exists.return_value = True
self.config.config_test = mock.Mock() self.config.config_test = mock.Mock()
@@ -268,8 +268,8 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.is_site_enabled, self.config.is_site_enabled,
"irrelevant") "irrelevant")
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
@mock.patch("certbot_apache.parser.subprocess.Popen") @mock.patch("certbot_apache.parser.subprocess.Popen")
def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script): def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script):
mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "") mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "")
@@ -287,7 +287,7 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertRaises( self.assertRaises(
errors.NotSupportedError, self.config.enable_mod, "ssl") errors.NotSupportedError, self.config.enable_mod, "ssl")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_enable_mod_no_disable(self, mock_exe_exists): def test_enable_mod_no_disable(self, mock_exe_exists):
mock_exe_exists.return_value = False mock_exe_exists.return_value = False
self.assertRaises( self.assertRaises(
@@ -695,7 +695,7 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.cleanup([achall1, achall2]) self.config.cleanup([achall1, achall2])
self.assertTrue(mock_restart.called) self.assertTrue(mock_restart.called)
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_get_version(self, mock_script): def test_get_version(self, mock_script):
mock_script.return_value = ( mock_script.return_value = (
"Server Version: Apache/2.4.2 (Debian)", "") "Server Version: Apache/2.4.2 (Debian)", "")
@@ -717,21 +717,21 @@ class MultipleVhostsTest(util.ApacheTest):
mock_script.side_effect = errors.SubprocessError("Can't find program") mock_script.side_effect = errors.SubprocessError("Can't find program")
self.assertRaises(errors.PluginError, self.config.get_version) self.assertRaises(errors.PluginError, self.config.get_version)
@mock.patch("certbot_apache.configurator.le_util.run_script") @mock.patch("certbot_apache.configurator.util.run_script")
def test_restart(self, _): def test_restart(self, _):
self.config.restart() self.config.restart()
@mock.patch("certbot_apache.configurator.le_util.run_script") @mock.patch("certbot_apache.configurator.util.run_script")
def test_restart_bad_process(self, mock_run_script): def test_restart_bad_process(self, mock_run_script):
mock_run_script.side_effect = [None, errors.SubprocessError] mock_run_script.side_effect = [None, errors.SubprocessError]
self.assertRaises(errors.MisconfigurationError, self.config.restart) self.assertRaises(errors.MisconfigurationError, self.config.restart)
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_config_test(self, _): def test_config_test(self, _):
self.config.config_test() self.config.config_test()
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_config_test_bad_process(self, mock_run_script): def test_config_test_bad_process(self, mock_run_script):
mock_run_script.side_effect = errors.SubprocessError mock_run_script.side_effect = errors.SubprocessError
@@ -771,7 +771,7 @@ class MultipleVhostsTest(util.ApacheTest):
@mock.patch("certbot_apache.configurator.ApacheConfigurator._get_http_vhost") @mock.patch("certbot_apache.configurator.ApacheConfigurator._get_http_vhost")
@mock.patch("certbot_apache.display_ops.select_vhost") @mock.patch("certbot_apache.display_ops.select_vhost")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_enhance_unknown_vhost(self, mock_exe, mock_sel_vhost, mock_get): def test_enhance_unknown_vhost(self, mock_exe, mock_sel_vhost, mock_get):
self.config.parser.modules.add("rewrite_module") self.config.parser.modules.add("rewrite_module")
mock_exe.return_value = True mock_exe.return_value = True
@@ -792,8 +792,8 @@ class MultipleVhostsTest(util.ApacheTest):
errors.PluginError, errors.PluginError,
self.config.enhance, "certbot.demo", "unknown_enhancement") self.config.enhance, "certbot.demo", "unknown_enhancement")
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_ocsp_stapling(self, mock_exe, mock_run_script): def test_ocsp_stapling(self, mock_exe, mock_run_script):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c") self.config.parser.modules.add("mod_ssl.c")
@@ -821,7 +821,7 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertEqual(len(stapling_cache_aug_path), 1) self.assertEqual(len(stapling_cache_aug_path), 1)
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_ocsp_stapling_twice(self, mock_exe): def test_ocsp_stapling_twice(self, mock_exe):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c") self.config.parser.modules.add("mod_ssl.c")
@@ -848,7 +848,7 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertEqual(len(stapling_cache_aug_path), 1) self.assertEqual(len(stapling_cache_aug_path), 1)
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_ocsp_unsupported_apache_version(self, mock_exe): def test_ocsp_unsupported_apache_version(self, mock_exe):
mock_exe.return_value = True mock_exe.return_value = True
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
@@ -871,8 +871,8 @@ class MultipleVhostsTest(util.ApacheTest):
http_vh = self.config._get_http_vhost(ssl_vh) http_vh = self.config._get_http_vhost(ssl_vh)
self.assertTrue(http_vh.ssl == False) self.assertTrue(http_vh.ssl == False)
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_http_header_hsts(self, mock_exe, _): def test_http_header_hsts(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c") self.config.parser.modules.add("mod_ssl.c")
@@ -909,8 +909,8 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.enhance, "encryption-example.demo", self.config.enhance, "encryption-example.demo",
"ensure-http-header", "Strict-Transport-Security") "ensure-http-header", "Strict-Transport-Security")
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_http_header_uir(self, mock_exe, _): def test_http_header_uir(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c") self.config.parser.modules.add("mod_ssl.c")
@@ -947,8 +947,8 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.enhance, "encryption-example.demo", self.config.enhance, "encryption-example.demo",
"ensure-http-header", "Upgrade-Insecure-Requests") "ensure-http-header", "Upgrade-Insecure-Requests")
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_redirect_well_formed_http(self, mock_exe, _): def test_redirect_well_formed_http(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True mock_exe.return_value = True
@@ -991,8 +991,8 @@ class MultipleVhostsTest(util.ApacheTest):
# pylint: disable=protected-access # pylint: disable=protected-access
self.assertTrue(self.config._is_rewrite_engine_on(self.vh_truth[3])) self.assertTrue(self.config._is_rewrite_engine_on(self.vh_truth[3]))
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
def test_redirect_with_existing_rewrite(self, mock_exe, _): def test_redirect_with_existing_rewrite(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock() self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True mock_exe.return_value = True
@@ -8,19 +8,19 @@ from certbot_apache import constants
class ConstantsTest(unittest.TestCase): class ConstantsTest(unittest.TestCase):
@mock.patch("certbot.le_util.get_os_info") @mock.patch("certbot.util.get_os_info")
def test_get_debian_value(self, os_info): def test_get_debian_value(self, os_info):
os_info.return_value = ('Debian', '', '') os_info.return_value = ('Debian', '', '')
self.assertEqual(constants.os_constant("vhost_root"), self.assertEqual(constants.os_constant("vhost_root"),
"/etc/apache2/sites-available") "/etc/apache2/sites-available")
@mock.patch("certbot.le_util.get_os_info") @mock.patch("certbot.util.get_os_info")
def test_get_centos_value(self, os_info): def test_get_centos_value(self, os_info):
os_info.return_value = ('CentOS Linux', '', '') os_info.return_value = ('CentOS Linux', '', '')
self.assertEqual(constants.os_constant("vhost_root"), self.assertEqual(constants.os_constant("vhost_root"),
"/etc/httpd/conf.d") "/etc/httpd/conf.d")
@mock.patch("certbot.le_util.get_os_info") @mock.patch("certbot.util.get_os_info")
def test_get_default_value(self, os_info): def test_get_default_value(self, os_info):
os_info.return_value = ('Nonexistent Linux', '', '') os_info.return_value = ('Nonexistent Linux', '', '')
self.assertEqual(constants.os_constant("vhost_root"), self.assertEqual(constants.os_constant("vhost_root"),
@@ -38,8 +38,8 @@ class TlsSniPerformTest(util.ApacheTest):
resp = self.sni.perform() resp = self.sni.perform()
self.assertEqual(len(resp), 0) self.assertEqual(len(resp), 0)
@mock.patch("certbot.le_util.exe_exists") @mock.patch("certbot.util.exe_exists")
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_perform1(self, _, mock_exists): def test_perform1(self, _, mock_exists):
mock_register = mock.Mock() mock_register = mock.Mock()
self.sni.configurator.reverter.register_undo_command = mock_register self.sni.configurator.reverter.register_undo_command = mock_register
+2 -2
View File
@@ -95,8 +95,8 @@ def get_apache_configurator(
in_progress_dir=os.path.join(backups, "IN_PROGRESS"), in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
work_dir=work_dir) work_dir=work_dir)
with mock.patch("certbot_apache.configurator.le_util.run_script"): with mock.patch("certbot_apache.configurator.util.run_script"):
with mock.patch("certbot_apache.configurator.le_util." with mock.patch("certbot_apache.configurator.util."
"exe_exists") as mock_exe_exists: "exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True mock_exe_exists.return_value = True
with mock.patch("certbot_apache.parser.ApacheParser." with mock.patch("certbot_apache.parser.ApacheParser."
+1 -1
View File
@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.7.0.dev0' version = '0.8.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
+54 -45
View File
@@ -19,7 +19,7 @@ XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share}
VENV_NAME="letsencrypt" VENV_NAME="letsencrypt"
VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"}
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
LE_AUTO_VERSION="0.6.0" LE_AUTO_VERSION="0.7.0"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -38,17 +38,6 @@ Help for certbot itself cannot be provided until it is installed.
All arguments are accepted and forwarded to the Certbot client when run." All arguments are accepted and forwarded to the Certbot client when run."
while getopts ":hnv" arg; do
case $arg in
h)
HELP=1;;
n)
ASSUME_YES=1;;
v)
VERBOSE=1;;
esac
done
for arg in "$@" ; do for arg in "$@" ; do
case "$arg" in case "$arg" in
--debug) --debug)
@@ -65,9 +54,26 @@ for arg in "$@" ; do
ASSUME_YES=1;; ASSUME_YES=1;;
--verbose) --verbose)
VERBOSE=1;; VERBOSE=1;;
-[!-]*)
while getopts ":hnv" short_arg $arg; do
case "$short_arg" in
h)
HELP=1;;
n)
ASSUME_YES=1;;
v)
VERBOSE=1;;
esac
done;;
esac esac
done done
if [ $BASENAME = "letsencrypt-auto" ]; then
# letsencrypt-auto does not respect --help or --yes for backwards compatibility
ASSUME_YES=1
HELP=0
fi
# certbot-auto needs root access to bootstrap OS dependencies, and # certbot-auto needs root access to bootstrap OS dependencies, and
# certbot itself needs root access for almost all modes of operation # certbot itself needs root access for almost all modes of operation
# The "normal" case is that sudo is used for the steps that need root, but # The "normal" case is that sudo is used for the steps that need root, but
@@ -107,12 +113,6 @@ else
SUDO= SUDO=
fi fi
if [ $BASENAME = "letsencrypt-auto" ]; then
# letsencrypt-auto does not respect --help or --yes for backwards compatibility
ASSUME_YES=1
HELP=0
fi
ExperimentalBootstrap() { ExperimentalBootstrap() {
# Arguments: Platform name, bootstrap function name # Arguments: Platform name, bootstrap function name
if [ "$DEBUG" = 1 ]; then if [ "$DEBUG" = 1 ]; then
@@ -425,7 +425,8 @@ BootstrapMac() {
$pkgcmd augeas $pkgcmd augeas
$pkgcmd dialog $pkgcmd dialog
if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" ]; then if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" \
-o "$(which python)" = "/usr/bin/python" ]; then
# We want to avoid using the system Python because it requires root to use pip. # We want to avoid using the system Python because it requires root to use pip.
# python.org, MacPorts or HomeBrew Python installations should all be OK. # python.org, MacPorts or HomeBrew Python installations should all be OK.
echo "Installing python..." echo "Installing python..."
@@ -435,7 +436,8 @@ BootstrapMac() {
# Workaround for _dlopen not finding augeas on OS X # Workaround for _dlopen not finding augeas on OS X
if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then
echo "Applying augeas workaround" echo "Applying augeas workaround"
$SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib $SUDO mkdir -p /usr/local/lib/
$SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/
fi fi
if ! hash pip 2>/dev/null; then if ! hash pip 2>/dev/null; then
@@ -451,6 +453,11 @@ BootstrapMac() {
fi fi
} }
BootstrapSmartOS() {
pkgin update
pkgin -y install 'gcc49' 'py27-augeas' 'py27-virtualenv'
}
# Install required OS packages: # Install required OS packages:
Bootstrap() { Bootstrap() {
@@ -483,8 +490,10 @@ Bootstrap() {
ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd
elif uname | grep -iq Darwin ; then elif uname | grep -iq Darwin ; then
ExperimentalBootstrap "Mac OS X" BootstrapMac ExperimentalBootstrap "Mac OS X" BootstrapMac
elif grep -iq "Amazon Linux" /etc/issue ; then elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
ExperimentalBootstrap "Joyent SmartOS Zone" BootstrapSmartOS
else else
echo "Sorry, I don't know how to bootstrap Certbot on your operating system!" echo "Sorry, I don't know how to bootstrap Certbot on your operating system!"
echo echo
@@ -523,6 +532,7 @@ if [ "$1" = "--le-auto-phase2" ]; then
echo "Installing Python packages..." echo "Installing Python packages..."
TEMP_DIR=$(TempDir) TEMP_DIR=$(TempDir)
trap 'rm -rf "$TEMP_DIR"' EXIT
# There is no $ interpolation due to quotes on starting heredoc delimiter. # There is no $ interpolation due to quotes on starting heredoc delimiter.
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt"
@@ -706,21 +716,21 @@ mock==1.0.1 \
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE.
acme==0.6.0 \ acme==0.7.0 \
--hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ --hash=sha256:6e61dba343806ad4cb27af84628152abc9e83a0fa24be6065587d2b46f340d7a \
--hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 --hash=sha256:9f75a1947978402026b741bdee8a18fc5a1cfd539b78e523b7e5f279bf18eeb9
certbot==0.6.0 \ certbot==0.7.0 \
--hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ --hash=sha256:55604e43d231ac226edefed8dc110d792052095c3d75ad0e4a228ae0989fe5fd \
--hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d --hash=sha256:ad5083d75e16d1ab806802d3a32f34973b6d7adaf083aee87e07a6c1359efe88
certbot-apache==0.6.0 \ certbot-apache==0.7.0 \
--hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ --hash=sha256:5ab5ed9b2af6c7db9495ce1491122798e9d0764e3df8f0843d11d89690bf7f88 \
--hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 --hash=sha256:1ddbfaf01bcb0b05c0dcc8b2ebd37637f080cf798151e8140c20c9f5fe7bae75
letsencrypt==0.6.0 \ letsencrypt==0.7.0 \
--hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
letsencrypt-apache==0.6.0 \ letsencrypt-apache==0.7.0 \
--hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ --hash=sha256:10445980a6afc810325ea22a56e269229999120848f6c0b323b00275696b5c80 \
--hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 --hash=sha256:3f4656088a18e4efea7cd7eb4965e14e8d901f3b64f4691e79cafd0bb91890f0
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@@ -880,7 +890,6 @@ UNLIKELY_EOF
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
PIP_STATUS=$? PIP_STATUS=$?
set -e set -e
rm -rf "$TEMP_DIR"
if [ "$PIP_STATUS" != 0 ]; then if [ "$PIP_STATUS" != 0 ]; then
# Report error. (Otherwise, be quiet.) # Report error. (Otherwise, be quiet.)
echo "Had a problem while installing Python packages:" echo "Had a problem while installing Python packages:"
@@ -890,14 +899,16 @@ UNLIKELY_EOF
fi fi
echo "Installation succeeded." echo "Installation succeeded."
fi fi
echo "Requesting root privileges to run certbot..." if [ -n "$SUDO" ]; then
# SUDO is su wrapper or sudo
echo "Requesting root privileges to run certbot..."
echo " $VENV_BIN/letsencrypt" "$@"
fi
if [ -z "$SUDO_ENV" ] ; then if [ -z "$SUDO_ENV" ] ; then
# SUDO is su wrapper / noop # SUDO is su wrapper / noop
echo " " $SUDO "$VENV_BIN/letsencrypt" "$@"
$SUDO "$VENV_BIN/letsencrypt" "$@" $SUDO "$VENV_BIN/letsencrypt" "$@"
else else
# sudo # sudo
echo " " $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@"
$SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@"
fi fi
@@ -923,8 +934,8 @@ else
fi fi
if [ "$NO_SELF_UPGRADE" != 1 ]; then if [ "$NO_SELF_UPGRADE" != 1 ]; then
echo "Checking for new version..."
TEMP_DIR=$(TempDir) TEMP_DIR=$(TempDir)
trap 'rm -rf "$TEMP_DIR"' EXIT
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py" cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py"
"""Do downloading and JSON parsing without additional dependencies. :: """Do downloading and JSON parsing without additional dependencies. ::
@@ -997,7 +1008,7 @@ def latest_stable_version(get):
"""Return the latest stable release of letsencrypt.""" """Return the latest stable release of letsencrypt."""
metadata = loads(get( metadata = loads(get(
environ.get('LE_AUTO_JSON_URL', environ.get('LE_AUTO_JSON_URL',
'https://pypi.python.org/pypi/letsencrypt/json'))) 'https://pypi.python.org/pypi/certbot/json')))
# metadata['info']['version'] actually returns the latest of any kind of # metadata['info']['version'] actually returns the latest of any kind of
# release release, contrary to https://wiki.python.org/moin/PyPIJSON. # release release, contrary to https://wiki.python.org/moin/PyPIJSON.
# The regex is a sufficient regex for picking out prereleases for most # The regex is a sufficient regex for picking out prereleases for most
@@ -1016,7 +1027,7 @@ def verified_new_le_auto(get, tag, temp_dir):
""" """
le_auto_dir = environ.get( le_auto_dir = environ.get(
'LE_AUTO_DIR_TEMPLATE', 'LE_AUTO_DIR_TEMPLATE',
'https://raw.githubusercontent.com/letsencrypt/letsencrypt/%s/' 'https://raw.githubusercontent.com/certbot/certbot/%s/'
'letsencrypt-auto-source/') % tag 'letsencrypt-auto-source/') % tag
write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto') write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto')
write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig') write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig')
@@ -1079,8 +1090,6 @@ UNLIKELY_EOF
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
# cp is unlikely to fail (esp. under sudo) if the rm doesn't. # cp is unlikely to fail (esp. under sudo) if the rm doesn't.
$SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
# TODO: Clean up temp dir safely, even if it has quotes in its path.
rm -rf "$TEMP_DIR"
fi # A newer version is available. fi # A newer version is available.
fi # Self-upgrading is allowed. fi # Self-upgrading is allowed.
@@ -47,10 +47,10 @@ class Proxy(configurators_common.Proxy):
"certbot_apache.parser.subprocess", "certbot_apache.parser.subprocess",
mock_subprocess).start() mock_subprocess).start()
mock.patch( mock.patch(
"certbot.le_util.subprocess", "certbot.util.subprocess",
mock_subprocess).start() mock_subprocess).start()
mock.patch( mock.patch(
"certbot_apache.configurator.le_util.exe_exists", "certbot_apache.configurator.util.exe_exists",
_is_apache_command).start() _is_apache_command).start()
patch = mock.patch( patch = mock.patch(
+1 -1
View File
@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.7.0.dev0' version = '0.8.0.dev0'
install_requires = [ install_requires = [
'certbot=={0}'.format(version), 'certbot=={0}'.format(version),
+7 -7
View File
@@ -17,7 +17,7 @@ from certbot import constants as core_constants
from certbot import crypto_util from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot import reverter from certbot import reverter
from certbot.plugins import common from certbot.plugins import common
@@ -111,7 +111,7 @@ class NginxConfigurator(common.Plugin):
:raises .errors.MisconfigurationError: If Nginx is misconfigured :raises .errors.MisconfigurationError: If Nginx is misconfigured
""" """
# Verify Nginx is installed # Verify Nginx is installed
if not le_util.exe_exists(self.conf('ctl')): if not util.exe_exists(self.conf('ctl')):
raise errors.NoInstallationError raise errors.NoInstallationError
# Make sure configuration is valid # Make sure configuration is valid
@@ -318,7 +318,7 @@ class NginxConfigurator(common.Plugin):
cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()]) cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
cert_pem = OpenSSL.crypto.dump_certificate( cert_pem = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert) OpenSSL.crypto.FILETYPE_PEM, cert)
cert_file, cert_path = le_util.unique_file(os.path.join(tmp_dir, "cert.pem")) cert_file, cert_path = util.unique_file(os.path.join(tmp_dir, "cert.pem"))
with cert_file: with cert_file:
cert_file.write(cert_pem) cert_file.write(cert_pem)
return cert_path, le_key.file return cert_path, le_key.file
@@ -426,7 +426,7 @@ class NginxConfigurator(common.Plugin):
""" """
try: try:
le_util.run_script([self.conf('ctl'), "-c", self.nginx_conf, "-t"]) util.run_script([self.conf('ctl'), "-c", self.nginx_conf, "-t"])
except errors.SubprocessError as err: except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err)) raise errors.MisconfigurationError(str(err))
@@ -439,11 +439,11 @@ class NginxConfigurator(common.Plugin):
""" """
uid = os.geteuid() uid = os.geteuid()
le_util.make_or_verify_dir( util.make_or_verify_dir(
self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid) self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid)
le_util.make_or_verify_dir( util.make_or_verify_dir(
self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid) self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid)
le_util.make_or_verify_dir( util.make_or_verify_dir(
self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid) self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid)
def get_version(self): def get_version(self):
@@ -30,7 +30,7 @@ class NginxConfiguratorTest(util.NginxTest):
shutil.rmtree(self.config_dir) shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir) shutil.rmtree(self.work_dir)
@mock.patch("certbot_nginx.configurator.le_util.exe_exists") @mock.patch("certbot_nginx.configurator.util.exe_exists")
def test_prepare_no_install(self, mock_exe_exists): def test_prepare_no_install(self, mock_exe_exists):
mock_exe_exists.return_value = False mock_exe_exists.return_value = False
self.assertRaises( self.assertRaises(
@@ -40,7 +40,7 @@ class NginxConfiguratorTest(util.NginxTest):
self.assertEquals((1, 6, 2), self.config.version) self.assertEquals((1, 6, 2), self.config.version)
self.assertEquals(5, len(self.config.parser.parsed)) self.assertEquals(5, len(self.config.parser.parsed))
@mock.patch("certbot_nginx.configurator.le_util.exe_exists") @mock.patch("certbot_nginx.configurator.util.exe_exists")
@mock.patch("certbot_nginx.configurator.subprocess.Popen") @mock.patch("certbot_nginx.configurator.subprocess.Popen")
def test_prepare_initializes_version(self, mock_popen, mock_exe_exists): def test_prepare_initializes_version(self, mock_popen, mock_exe_exists):
mock_popen().communicate.return_value = ( mock_popen().communicate.return_value = (
@@ -362,11 +362,11 @@ class NginxConfiguratorTest(util.NginxTest):
mock_popen.side_effect = OSError("Can't find program") mock_popen.side_effect = OSError("Can't find program")
self.assertRaises(errors.MisconfigurationError, self.config.restart) self.assertRaises(errors.MisconfigurationError, self.config.restart)
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_config_test(self, _): def test_config_test(self, _):
self.config.config_test() self.config.config_test()
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_config_test_bad_process(self, mock_run_script): def test_config_test_bad_process(self, mock_run_script):
mock_run_script.side_effect = errors.SubprocessError mock_run_script.side_effect = errors.SubprocessError
self.assertRaises(errors.MisconfigurationError, self.config.config_test) self.assertRaises(errors.MisconfigurationError, self.config.config_test)
+1 -1
View File
@@ -51,7 +51,7 @@ def get_nginx_configurator(
with mock.patch("certbot_nginx.configurator.NginxConfigurator." with mock.patch("certbot_nginx.configurator.NginxConfigurator."
"config_test"): "config_test"):
with mock.patch("certbot_nginx.configurator.le_util." with mock.patch("certbot_nginx.configurator.util."
"exe_exists") as mock_exe_exists: "exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True mock_exe_exists.return_value = True
config = configurator.NginxConfigurator( config = configurator.NginxConfigurator(
+1 -1
View File
@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
version = '0.7.0.dev0' version = '0.8.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
+1 -1
View File
@@ -1,4 +1,4 @@
"""Certbot client.""" """Certbot client."""
# version number like 1.2.3a0, must have at least 2 parts, like 1.2 # version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '0.7.0.dev0' __version__ = '0.8.0.dev0'
+6 -6
View File
@@ -16,7 +16,7 @@ from acme import messages
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -130,7 +130,7 @@ class AccountFileStorage(interfaces.AccountStorage):
""" """
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
le_util.make_or_verify_dir(config.accounts_dir, 0o700, os.geteuid(), util.make_or_verify_dir(config.accounts_dir, 0o700, os.geteuid(),
self.config.strict_permissions) self.config.strict_permissions)
def _account_dir_path(self, account_id): def _account_dir_path(self, account_id):
@@ -198,14 +198,14 @@ class AccountFileStorage(interfaces.AccountStorage):
def _save(self, account, regr_only): def _save(self, account, regr_only):
account_dir_path = self._account_dir_path(account.id) account_dir_path = self._account_dir_path(account.id)
le_util.make_or_verify_dir(account_dir_path, 0o700, os.geteuid(), util.make_or_verify_dir(account_dir_path, 0o700, os.geteuid(),
self.config.strict_permissions) self.config.strict_permissions)
try: try:
with open(self._regr_path(account_dir_path), "w") as regr_file: with open(self._regr_path(account_dir_path), "w") as regr_file:
regr_file.write(account.regr.json_dumps()) regr_file.write(account.regr.json_dumps())
if not regr_only: if not regr_only:
with le_util.safe_open(self._key_path(account_dir_path), with util.safe_open(self._key_path(account_dir_path),
"w", chmod=0o400) as key_file: "w", chmod=0o400) as key_file:
key_file.write(account.key.json_dumps()) key_file.write(account.key.json_dumps())
with open(self._metadata_path( with open(self._metadata_path(
account_dir_path), "w") as metadata_file: account_dir_path), "w") as metadata_file:
+3 -3
View File
@@ -17,7 +17,7 @@ from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import hooks from certbot import hooks
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot.plugins import disco as plugins_disco from certbot.plugins import disco as plugins_disco
import certbot.plugins.selection as plugin_selection import certbot.plugins.selection as plugin_selection
@@ -518,7 +518,7 @@ class HelpfulArgumentParser(object):
:param int nargs: Number of arguments the option takes. :param int nargs: Number of arguments the option takes.
""" """
le_util.add_deprecated_argument( util.add_deprecated_argument(
self.parser.add_argument, argument_name, num_args) self.parser.add_argument, argument_name, num_args)
def add_group(self, topic, **kwargs): def add_group(self, topic, **kwargs):
@@ -962,7 +962,7 @@ def add_domains(args_or_config, domains):
""" """
validated_domains = [] validated_domains = []
for domain in domains.split(","): for domain in domains.split(","):
domain = le_util.enforce_domain_sanity(domain.strip()) domain = util.enforce_domain_sanity(domain.strip())
validated_domains.append(domain) validated_domains.append(domain)
if domain not in args_or_config.domains: if domain not in args_or_config.domains:
args_or_config.domains.append(domain) args_or_config.domains.append(domain)
+11 -11
View File
@@ -21,7 +21,7 @@ from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import error_handler from certbot import error_handler
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot import reverter from certbot import reverter
from certbot import storage from certbot import storage
from certbot import cli from certbot import cli
@@ -53,7 +53,7 @@ def _determine_user_agent(config):
if config.user_agent is None: if config.user_agent is None:
ua = "CertbotACMEClient/{0} ({1}) Authenticator/{2} Installer/{3}" ua = "CertbotACMEClient/{0} ({1}) Authenticator/{2} Installer/{3}"
ua = ua.format(certbot.__version__, " ".join(le_util.get_os_info()), ua = ua.format(certbot.__version__, util.get_os_info_ua(),
config.authenticator, config.installer) config.authenticator, config.installer)
else: else:
ua = config.user_agent ua = config.user_agent
@@ -198,7 +198,7 @@ class Client(object):
consistent with identifiers present in the `csr`. consistent with identifiers present in the `csr`.
:param list domains: Domain names. :param list domains: Domain names.
:param .le_util.CSR csr: DER-encoded Certificate Signing :param .util.CSR csr: DER-encoded Certificate Signing
Request. The key used to generate this CSR can be different Request. The key used to generate this CSR can be different
than `authkey`. than `authkey`.
:param list authzr: List of :param list authzr: List of
@@ -237,8 +237,8 @@ class Client(object):
:returns: `.CertificateResource`, certificate chain (as :returns: `.CertificateResource`, certificate chain (as
returned by `.fetch_chain`), and newly generated private key returned by `.fetch_chain`), and newly generated private key
(`.le_util.Key`) and DER-encoded Certificate Signing Request (`.util.Key`) and DER-encoded Certificate Signing Request
(`.le_util.CSR`). (`.util.CSR`).
:rtype: tuple :rtype: tuple
""" """
@@ -312,7 +312,7 @@ class Client(object):
""" """
for path in cert_path, chain_path, fullchain_path: for path in cert_path, chain_path, fullchain_path:
le_util.make_or_verify_dir( util.make_or_verify_dir(
os.path.dirname(path), 0o755, os.geteuid(), os.path.dirname(path), 0o755, os.geteuid(),
self.config.strict_permissions) self.config.strict_permissions)
@@ -504,9 +504,9 @@ def validate_key_csr(privkey, csr=None):
If csr is left as None, only the key will be validated. If csr is left as None, only the key will be validated.
:param privkey: Key associated with CSR :param privkey: Key associated with CSR
:type privkey: :class:`certbot.le_util.Key` :type privkey: :class:`certbot.util.Key`
:param .le_util.CSR csr: CSR :param .util.CSR csr: CSR
:raises .errors.Error: when validation fails :raises .errors.Error: when validation fails
@@ -523,7 +523,7 @@ def validate_key_csr(privkey, csr=None):
if csr.form == "der": if csr.form == "der":
csr_obj = OpenSSL.crypto.load_certificate_request( csr_obj = OpenSSL.crypto.load_certificate_request(
OpenSSL.crypto.FILETYPE_ASN1, csr.data) OpenSSL.crypto.FILETYPE_ASN1, csr.data)
csr = le_util.CSR(csr.file, OpenSSL.crypto.dump_certificate( csr = util.CSR(csr.file, OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, csr_obj), "pem") OpenSSL.crypto.FILETYPE_PEM, csr_obj), "pem")
# If CSR is provided, it must be readable and valid. # If CSR is provided, it must be readable and valid.
@@ -586,10 +586,10 @@ def _open_pem_file(cli_arg_path, pem_path):
""" """
if cli.set_by_cli(cli_arg_path): if cli.set_by_cli(cli_arg_path):
return le_util.safe_open(pem_path, chmod=0o644),\ return util.safe_open(pem_path, chmod=0o644),\
os.path.abspath(pem_path) os.path.abspath(pem_path)
else: else:
uniq = le_util.unique_file(pem_path, 0o644) uniq = util.unique_file(pem_path, 0o644)
return uniq[0], os.path.abspath(uniq[1]) return uniq[0], os.path.abspath(uniq[1])
def _save_chain(chain_pem, chain_file): def _save_chain(chain_pem, chain_file):
+2 -2
View File
@@ -2,7 +2,7 @@
import logging import logging
import sys import sys
from certbot import le_util from certbot import util
class StreamHandler(logging.StreamHandler): class StreamHandler(logging.StreamHandler):
@@ -40,6 +40,6 @@ class StreamHandler(logging.StreamHandler):
if sys.version_info < (2, 7) if sys.version_info < (2, 7)
else super(StreamHandler, self).format(record)) else super(StreamHandler, self).format(record))
if self.colored and record.levelno >= self.red_level: if self.colored and record.levelno >= self.red_level:
return ''.join((le_util.ANSI_SGR_RED, out, le_util.ANSI_SGR_RESET)) return ''.join((util.ANSI_SGR_RED, out, util.ANSI_SGR_RESET))
else: else:
return out return out
+2 -2
View File
@@ -8,7 +8,7 @@ import zope.interface
from certbot import constants from certbot import constants
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
@zope.interface.implementer(interfaces.IConfig) @zope.interface.implementer(interfaces.IConfig)
@@ -132,4 +132,4 @@ def check_config_sanity(config):
if config.namespace.domains is not None: if config.namespace.domains is not None:
for domain in config.namespace.domains: for domain in config.namespace.domains:
# This may be redundant, but let's be paranoid # This may be redundant, but let's be paranoid
le_util.enforce_domain_sanity(domain) util.enforce_domain_sanity(domain)
+13 -14
View File
@@ -17,7 +17,7 @@ from acme import jose
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -37,7 +37,7 @@ def init_save_key(key_size, key_dir, keyname="key-certbot.pem"):
:param str keyname: Filename of key :param str keyname: Filename of key
:returns: Key :returns: Key
:rtype: :class:`certbot.le_util.Key` :rtype: :class:`certbot.util.Key`
:raises ValueError: If unable to generate the key given key_size. :raises ValueError: If unable to generate the key given key_size.
@@ -50,30 +50,29 @@ def init_save_key(key_size, key_dir, keyname="key-certbot.pem"):
config = zope.component.getUtility(interfaces.IConfig) config = zope.component.getUtility(interfaces.IConfig)
# Save file # Save file
le_util.make_or_verify_dir(key_dir, 0o700, os.geteuid(), util.make_or_verify_dir(key_dir, 0o700, os.geteuid(),
config.strict_permissions) config.strict_permissions)
key_f, key_path = le_util.unique_file( key_f, key_path = util.unique_file(os.path.join(key_dir, keyname), 0o600)
os.path.join(key_dir, keyname), 0o600)
with key_f: with key_f:
key_f.write(key_pem) key_f.write(key_pem)
logger.info("Generating key (%d bits): %s", key_size, key_path) logger.info("Generating key (%d bits): %s", key_size, key_path)
return le_util.Key(key_path, key_pem) return util.Key(key_path, key_pem)
def init_save_csr(privkey, names, path, csrname="csr-certbot.pem"): def init_save_csr(privkey, names, path, csrname="csr-certbot.pem"):
"""Initialize a CSR with the given private key. """Initialize a CSR with the given private key.
:param privkey: Key to include in the CSR :param privkey: Key to include in the CSR
:type privkey: :class:`certbot.le_util.Key` :type privkey: :class:`certbot.util.Key`
:param set names: `str` names to include in the CSR :param set names: `str` names to include in the CSR
:param str path: Certificate save directory. :param str path: Certificate save directory.
:returns: CSR :returns: CSR
:rtype: :class:`certbot.le_util.CSR` :rtype: :class:`certbot.util.CSR`
""" """
config = zope.component.getUtility(interfaces.IConfig) config = zope.component.getUtility(interfaces.IConfig)
@@ -82,16 +81,16 @@ def init_save_csr(privkey, names, path, csrname="csr-certbot.pem"):
must_staple=config.must_staple) must_staple=config.must_staple)
# Save CSR # Save CSR
le_util.make_or_verify_dir(path, 0o755, os.geteuid(), util.make_or_verify_dir(path, 0o755, os.geteuid(),
config.strict_permissions) config.strict_permissions)
csr_f, csr_filename = le_util.unique_file( csr_f, csr_filename = util.unique_file(
os.path.join(path, csrname), 0o644) os.path.join(path, csrname), 0o644)
csr_f.write(csr_pem) csr_f.write(csr_pem)
csr_f.close() csr_f.close()
logger.info("Creating CSR: %s", csr_filename) logger.info("Creating CSR: %s", csr_filename)
return le_util.CSR(csr_filename, csr_der, "der") return util.CSR(csr_filename, csr_der, "der")
# Lower level functions # Lower level functions
@@ -187,7 +186,7 @@ def import_csr_file(csrfile, data):
:param str data: contents of the CSR file :param str data: contents of the CSR file
:returns: (`OpenSSL.crypto.FILETYPE_PEM` or `OpenSSL.crypto.FILETYPE_ASN1`, :returns: (`OpenSSL.crypto.FILETYPE_PEM` or `OpenSSL.crypto.FILETYPE_ASN1`,
le_util.CSR object representing the CSR, util.CSR object representing the CSR,
list of domains requested in the CSR) list of domains requested in the CSR)
:rtype: tuple :rtype: tuple
@@ -200,7 +199,7 @@ def import_csr_file(csrfile, data):
logger.debug("CSR parse error (form=%s, typ=%s):", form, typ) logger.debug("CSR parse error (form=%s, typ=%s):", form, typ)
logger.debug(traceback.format_exc()) logger.debug(traceback.format_exc())
continue continue
return typ, le_util.CSR(file=csrfile, data=data, form=form), domains return typ, util.CSR(file=csrfile, data=data, form=form), domains
raise errors.Error("Failed to parse CSR file: {0}".format(csrfile)) raise errors.Error("Failed to parse CSR file: {0}".format(csrfile))
+4 -4
View File
@@ -6,7 +6,7 @@ import zope.component
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot.display import util as display_util from certbot.display import util as display_util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -58,7 +58,7 @@ def get_email(invalid=False, optional=True):
"--register-unsafely-without-email must be provided.") "--register-unsafely-without-email must be provided.")
else: else:
raise errors.Error("An e-mail address must be provided.") raise errors.Error("An e-mail address must be provided.")
elif le_util.safe_email(email): elif util.safe_email(email):
return email return email
elif suggest_unsafe: elif suggest_unsafe:
msg += unsafe_suggestion msg += unsafe_suggestion
@@ -134,7 +134,7 @@ def get_valid_domains(domains):
valid_domains = [] valid_domains = []
for domain in domains: for domain in domains:
try: try:
valid_domains.append(le_util.enforce_domain_sanity(domain)) valid_domains.append(util.enforce_domain_sanity(domain))
except errors.ConfigurationError: except errors.ConfigurationError:
continue continue
return valid_domains return valid_domains
@@ -178,7 +178,7 @@ def _choose_names_manually():
for i, domain in enumerate(domain_list): for i, domain in enumerate(domain_list):
try: try:
domain_list[i] = le_util.enforce_domain_sanity(domain) domain_list[i] = util.enforce_domain_sanity(domain)
except errors.ConfigurationError as e: except errors.ConfigurationError as e:
invalid_domains[domain] = e.message invalid_domains[domain] = e.message
+5 -5
View File
@@ -24,7 +24,7 @@ from certbot import constants
from certbot import errors from certbot import errors
from certbot import hooks from certbot import hooks
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot import log from certbot import log
from certbot import reporter from certbot import reporter
from certbot import renewal from certbot import renewal
@@ -229,7 +229,7 @@ def _find_duplicative_certs(config, domains):
cli_config = configuration.RenewerConfiguration(config) cli_config = configuration.RenewerConfiguration(config)
configs_dir = cli_config.renewal_configs_dir configs_dir = cli_config.renewal_configs_dir
# Verify the directory is there # Verify the directory is there
le_util.make_or_verify_dir(configs_dir, mode=0o755, uid=os.geteuid()) util.make_or_verify_dir(configs_dir, mode=0o755, uid=os.geteuid())
for renewal_file in renewal.renewal_conf_files(cli_config): for renewal_file in renewal.renewal_conf_files(cli_config):
try: try:
@@ -292,7 +292,7 @@ def _report_new_cert(config, cert_path, fullchain_path):
msg = ('Congratulations! Your certificate {0} been saved at {1}.' msg = ('Congratulations! Your certificate {0} been saved at {1}.'
' Your cert will expire on {2}. To obtain a new or tweaked version of this ' ' Your cert will expire on {2}. To obtain a new or tweaked version of this '
'certificate in the future, simply run {3} again{4}. ' 'certificate in the future, simply run {3} again{4}. '
'To non-interactively renew *all* of your ceriticates, run "{3} renew"' 'To non-interactively renew *all* of your certificates, run "{3} renew"'
.format(and_chain, path, expiry, cli.cli_command, verbswitch)) .format(and_chain, path, expiry, cli.cli_command, verbswitch))
reporter_util.add_message(msg, reporter_util.MEDIUM_PRIORITY) reporter_util.add_message(msg, reporter_util.MEDIUM_PRIORITY)
@@ -698,12 +698,12 @@ def main(cli_args=sys.argv[1:]):
# Setup logging ASAP, otherwise "No handlers could be found for # Setup logging ASAP, otherwise "No handlers could be found for
# logger ..." TODO: this should be done before plugins discovery # logger ..." TODO: this should be done before plugins discovery
for directory in config.config_dir, config.work_dir: for directory in config.config_dir, config.work_dir:
le_util.make_or_verify_dir( util.make_or_verify_dir(
directory, constants.CONFIG_DIRS_MODE, os.geteuid(), directory, constants.CONFIG_DIRS_MODE, os.geteuid(),
"--strict-permissions" in cli_args) "--strict-permissions" in cli_args)
# TODO: logs might contain sensitive data such as contents of the # TODO: logs might contain sensitive data such as contents of the
# private key! #525 # private key! #525
le_util.make_or_verify_dir( util.make_or_verify_dir(
config.logs_dir, 0o700, os.geteuid(), "--strict-permissions" in cli_args) config.logs_dir, 0o700, os.geteuid(), "--strict-permissions" in cli_args)
setup_logging(config, _cli_log_handler, logfile='letsencrypt.log') setup_logging(config, _cli_log_handler, logfile='letsencrypt.log')
cli.possible_deprecation_warning(config) cli.possible_deprecation_warning(config)
+2 -2
View File
@@ -12,7 +12,7 @@ from acme.jose import util as jose_util
from certbot import constants from certbot import constants
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
def option_namespace(name): def option_namespace(name):
@@ -255,7 +255,7 @@ class TLSSNI01(object):
# Write out challenge cert and key # Write out challenge cert and key
with open(cert_path, "wb") as cert_chall_fd: with open(cert_path, "wb") as cert_chall_fd:
cert_chall_fd.write(cert_pem) cert_chall_fd.write(cert_pem)
with le_util.safe_open(key_path, 'wb', chmod=0o400) as key_file: with util.safe_open(key_path, 'wb', chmod=0o400) as key_file:
key_file.write(key_pem) key_file.write(key_pem)
return response return response
+1 -1
View File
@@ -193,7 +193,7 @@ class TLSSNI01Test(unittest.TestCase):
with mock.patch("certbot.plugins.common.open", with mock.patch("certbot.plugins.common.open",
mock_open, create=True): mock_open, create=True):
with mock.patch("certbot.plugins.common.le_util.safe_open", with mock.patch("certbot.plugins.common.util.safe_open",
mock_safe_open): mock_safe_open):
# pylint: disable=protected-access # pylint: disable=protected-access
self.assertEqual(response, self.sni._setup_challenge_cert( self.assertEqual(response, self.sni._setup_challenge_cert(
+2 -2
View File
@@ -18,7 +18,7 @@ from certbot import constants
from certbot import crypto_util from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot import hooks from certbot import hooks
from certbot import storage from certbot import storage
from certbot.plugins import disco as plugins_disco from certbot.plugins import disco as plugins_disco
@@ -86,7 +86,7 @@ def _reconstitute(config, full_path):
return None return None
try: try:
config.domains = [le_util.enforce_domain_sanity(d) config.domains = [util.enforce_domain_sanity(d)
for d in renewal_candidate.names()] for d in renewal_candidate.names()]
except errors.ConfigurationError as error: except errors.ConfigurationError as error:
logger.warning("Renewal configuration file %s references a cert " logger.warning("Renewal configuration file %s references a cert "
+12 -5
View File
@@ -11,11 +11,16 @@ from six.moves import queue # pylint: disable=import-error
import zope.interface import zope.interface
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Store the pid of the process that first imported this module so that
# atexit_print_messages side-effects such as error reporting can be limited to
# this process and not any fork()'d children.
INITIAL_PID = os.getpid()
@zope.interface.implementer(interfaces.IReporter) @zope.interface.implementer(interfaces.IReporter)
class Reporter(object): class Reporter(object):
@@ -55,12 +60,14 @@ class Reporter(object):
self.messages.put(self._msg_type(priority, msg, on_crash)) self.messages.put(self._msg_type(priority, msg, on_crash))
logger.info("Reporting to user: %s", msg) logger.info("Reporting to user: %s", msg)
def atexit_print_messages(self, pid=os.getpid()): def atexit_print_messages(self, pid=None):
"""Function to be registered with atexit to print messages. """Function to be registered with atexit to print messages.
:param int pid: Process ID :param int pid: Process ID
""" """
if pid is None:
pid = INITIAL_PID
# This ensures that messages are only printed from the process that # This ensures that messages are only printed from the process that
# created the Reporter. # created the Reporter.
if pid == os.getpid(): if pid == os.getpid():
@@ -79,7 +86,7 @@ class Reporter(object):
bold_on = sys.stdout.isatty() bold_on = sys.stdout.isatty()
if not self.config.quiet: if not self.config.quiet:
if bold_on: if bold_on:
print(le_util.ANSI_SGR_BOLD) print(util.ANSI_SGR_BOLD)
print('IMPORTANT NOTES:') print('IMPORTANT NOTES:')
first_wrapper = textwrap.TextWrapper( first_wrapper = textwrap.TextWrapper(
initial_indent=' - ', initial_indent=' - ',
@@ -101,7 +108,7 @@ class Reporter(object):
if no_exception or msg.on_crash: if no_exception or msg.on_crash:
if bold_on and msg.priority > self.HIGH_PRIORITY: if bold_on and msg.priority > self.HIGH_PRIORITY:
if not self.config.quiet: if not self.config.quiet:
sys.stdout.write(le_util.ANSI_SGR_RESET) sys.stdout.write(util.ANSI_SGR_RESET)
bold_on = False bold_on = False
lines = msg.text.splitlines() lines = msg.text.splitlines()
print(first_wrapper.fill(lines[0])) print(first_wrapper.fill(lines[0]))
@@ -109,4 +116,4 @@ class Reporter(object):
print("\n".join( print("\n".join(
next_wrapper.fill(line) for line in lines[1:])) next_wrapper.fill(line) for line in lines[1:]))
if bold_on and not self.config.quiet: if bold_on and not self.config.quiet:
sys.stdout.write(le_util.ANSI_SGR_RESET) sys.stdout.write(util.ANSI_SGR_RESET)
+5 -5
View File
@@ -13,7 +13,7 @@ import zope.component
from certbot import constants from certbot import constants
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot.display import util as display_util from certbot.display import util as display_util
@@ -33,7 +33,7 @@ class Reverter(object):
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
le_util.make_or_verify_dir( 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) self.config.strict_permissions)
@@ -185,7 +185,7 @@ class Reverter(object):
:raises .ReverterError: if unable to add checkpoint :raises .ReverterError: if unable to add checkpoint
""" """
le_util.make_or_verify_dir( 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) self.config.strict_permissions)
@@ -281,7 +281,7 @@ class Reverter(object):
csvreader = csv.reader(csvfile) csvreader = csv.reader(csvfile)
for command in reversed(list(csvreader)): for command in reversed(list(csvreader)):
try: try:
le_util.run_script(command) util.run_script(command)
except errors.SubprocessError: except errors.SubprocessError:
logger.error( logger.error(
"Unable to run undo command: %s", " ".join(command)) "Unable to run undo command: %s", " ".join(command))
@@ -397,7 +397,7 @@ class Reverter(object):
else: else:
cp_dir = self.config.in_progress_dir cp_dir = self.config.in_progress_dir
le_util.make_or_verify_dir( 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) self.config.strict_permissions)
+4 -4
View File
@@ -13,12 +13,12 @@ from certbot import constants
from certbot import crypto_util from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import error_handler from certbot import error_handler
from certbot import le_util from certbot import util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
ALL_FOUR = ("cert", "privkey", "chain", "fullchain") ALL_FOUR = ("cert", "privkey", "chain", "fullchain")
CURRENT_VERSION = le_util.get_strict_version(certbot.__version__) CURRENT_VERSION = util.get_strict_version(certbot.__version__)
def config_with_defaults(config=None): def config_with_defaults(config=None):
@@ -264,7 +264,7 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
conf_version = self.configuration.get("version") conf_version = self.configuration.get("version")
if (conf_version is not None and if (conf_version is not None and
le_util.get_strict_version(conf_version) > CURRENT_VERSION): util.get_strict_version(conf_version) > CURRENT_VERSION):
logger.warning( logger.warning(
"Attempting to parse the version %s renewal configuration " "Attempting to parse the version %s renewal configuration "
"file found at %s with version %s of Certbot. This might not " "file found at %s with version %s of Certbot. This might not "
@@ -769,7 +769,7 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
if not os.path.exists(i): if not os.path.exists(i):
os.makedirs(i, 0o700) os.makedirs(i, 0o700)
logger.debug("Creating directory %s.", i) logger.debug("Creating directory %s.", i)
config_file, config_filename = le_util.unique_lineage_name( config_file, config_filename = util.unique_lineage_name(
cli_config.renewal_configs_dir, lineagename) cli_config.renewal_configs_dir, lineagename)
if not config_filename.endswith(".conf"): if not config_filename.endswith(".conf"):
raise errors.CertStorageError( raise errors.CertStorageError(
+2 -2
View File
@@ -11,7 +11,7 @@ from acme import messages
from certbot import achallenges from certbot import achallenges
from certbot import errors from certbot import errors
from certbot import le_util from certbot import util
from certbot.tests import acme_util from certbot.tests import acme_util
@@ -69,7 +69,7 @@ class GetAuthorizationsTest(unittest.TestCase):
self.mock_auth.perform.side_effect = gen_auth_resp self.mock_auth.perform.side_effect = gen_auth_resp
self.mock_account = mock.Mock(key=le_util.Key("file_path", "PEM")) self.mock_account = mock.Mock(key=util.Key("file_path", "PEM"))
self.mock_net = mock.MagicMock(spec=acme_client.Client) self.mock_net = mock.MagicMock(spec=acme_client.Client)
self.handler = AuthHandler( self.handler = AuthHandler(
+5 -5
View File
@@ -22,7 +22,7 @@ from certbot import configuration
from certbot import constants from certbot import constants
from certbot import crypto_util from certbot import crypto_util
from certbot import errors from certbot import errors
from certbot import le_util from certbot import util
from certbot import main from certbot import main
from certbot import renewal from certbot import renewal
from certbot import storage from certbot import storage
@@ -171,13 +171,13 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
with mock.patch('certbot.main.client.acme_client.ClientNetwork') as acme_net: with mock.patch('certbot.main.client.acme_client.ClientNetwork') as acme_net:
self._call_no_clientmock(args) self._call_no_clientmock(args)
os_ver = " ".join(le_util.get_os_info()) os_ver = util.get_os_info_ua()
ua = acme_net.call_args[1]["user_agent"] ua = acme_net.call_args[1]["user_agent"]
self.assertTrue(os_ver in ua) self.assertTrue(os_ver in ua)
import platform import platform
plat = platform.platform() plat = platform.platform()
if "linux" in plat.lower(): if "linux" in plat.lower():
self.assertTrue(platform.linux_distribution()[0] in ua) self.assertTrue(util.get_os_info_ua() in ua)
with mock.patch('certbot.main.client.acme_client.ClientNetwork') as acme_net: with mock.patch('certbot.main.client.acme_client.ClientNetwork') as acme_net:
ua = "bandersnatch" ua = "bandersnatch"
@@ -209,7 +209,7 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
'--key-path', 'key', '--chain-path', 'chain']) '--key-path', 'key', '--chain-path', 'chain'])
self.assertEqual(mock_pick_installer.call_count, 1) self.assertEqual(mock_pick_installer.call_count, 1)
@mock.patch('certbot.le_util.exe_exists') @mock.patch('certbot.util.exe_exists')
def test_configurator_selection(self, mock_exe_exists): def test_configurator_selection(self, mock_exe_exists):
mock_exe_exists.return_value = True mock_exe_exists.return_value = True
real_plugins = disco.PluginsRegistry.find_all() real_plugins = disco.PluginsRegistry.find_all()
@@ -1063,7 +1063,7 @@ class DuplicativeCertsTest(storage_test.BaseRenewableCertTest):
def tearDown(self): def tearDown(self):
shutil.rmtree(self.tempdir) shutil.rmtree(self.tempdir)
@mock.patch('certbot.le_util.make_or_verify_dir') @mock.patch('certbot.util.make_or_verify_dir')
def test_find_duplicative_names(self, unused_makedir): def test_find_duplicative_names(self, unused_makedir):
from certbot.main import _find_duplicative_certs from certbot.main import _find_duplicative_certs
test_cert = test_util.load_vector('cert-san.pem') test_cert = test_util.load_vector('cert-san.pem')
+3 -3
View File
@@ -11,7 +11,7 @@ from acme import jose
from certbot import account from certbot import account
from certbot import errors from certbot import errors
from certbot import le_util from certbot import util
from certbot.tests import test_util from certbot.tests import test_util
@@ -137,7 +137,7 @@ class ClientTest(unittest.TestCase):
@mock.patch("certbot.client.logger") @mock.patch("certbot.client.logger")
def test_obtain_certificate_from_csr(self, mock_logger): def test_obtain_certificate_from_csr(self, mock_logger):
self._mock_obtain_certificate() self._mock_obtain_certificate()
test_csr = le_util.CSR(form="der", file=None, data=CSR_SAN) test_csr = util.CSR(form="der", file=None, data=CSR_SAN)
auth_handler = self.client.auth_handler auth_handler = self.client.auth_handler
authzr = auth_handler.get_authorizations(self.eg_domains, False) authzr = auth_handler.get_authorizations(self.eg_domains, False)
@@ -172,7 +172,7 @@ class ClientTest(unittest.TestCase):
def test_obtain_certificate(self, mock_crypto_util): def test_obtain_certificate(self, mock_crypto_util):
self._mock_obtain_certificate() self._mock_obtain_certificate()
csr = le_util.CSR(form="der", file=None, data=CSR_SAN) csr = util.CSR(form="der", file=None, data=CSR_SAN)
mock_crypto_util.init_save_csr.return_value = csr mock_crypto_util.init_save_csr.return_value = csr
mock_crypto_util.init_save_key.return_value = mock.sentinel.key mock_crypto_util.init_save_key.return_value = mock.sentinel.key
domains = ["example.com", "www.example.com"] domains = ["example.com", "www.example.com"]
+3 -3
View File
@@ -4,7 +4,7 @@ import unittest
import six import six
from certbot import le_util from certbot import util
class StreamHandlerTest(unittest.TestCase): class StreamHandlerTest(unittest.TestCase):
@@ -32,9 +32,9 @@ class StreamHandlerTest(unittest.TestCase):
self.logger.debug(msg) self.logger.debug(msg)
self.assertEqual(self.stream.getvalue(), self.assertEqual(self.stream.getvalue(),
'{0}{1}{2}\n'.format(le_util.ANSI_SGR_RED, '{0}{1}{2}\n'.format(util.ANSI_SGR_RED,
msg, msg,
le_util.ANSI_SGR_RESET)) util.ANSI_SGR_RESET))
if __name__ == "__main__": if __name__ == "__main__":
+8 -8
View File
@@ -10,7 +10,7 @@ import zope.component
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot import le_util from certbot import util
from certbot.tests import test_util from certbot.tests import test_util
@@ -63,7 +63,7 @@ class InitSaveCSRTest(unittest.TestCase):
shutil.rmtree(self.csr_dir) shutil.rmtree(self.csr_dir)
@mock.patch('certbot.crypto_util.make_csr') @mock.patch('certbot.crypto_util.make_csr')
@mock.patch('certbot.crypto_util.le_util.make_or_verify_dir') @mock.patch('certbot.crypto_util.util.make_or_verify_dir')
def test_it(self, unused_mock_verify, mock_csr): def test_it(self, unused_mock_verify, mock_csr):
from certbot.crypto_util import init_save_csr from certbot.crypto_util import init_save_csr
@@ -174,9 +174,9 @@ class ImportCSRFileTest(unittest.TestCase):
self.assertEqual( self.assertEqual(
(OpenSSL.crypto.FILETYPE_ASN1, (OpenSSL.crypto.FILETYPE_ASN1,
le_util.CSR(file=csrfile, util.CSR(file=csrfile,
data=data, data=data,
form="der"), form="der"),
["example.com"],), ["example.com"],),
self._call(csrfile, data)) self._call(csrfile, data))
@@ -186,9 +186,9 @@ class ImportCSRFileTest(unittest.TestCase):
self.assertEqual( self.assertEqual(
(OpenSSL.crypto.FILETYPE_PEM, (OpenSSL.crypto.FILETYPE_PEM,
le_util.CSR(file=csrfile, util.CSR(file=csrfile,
data=data, data=data,
form="pem"), form="pem"),
["example.com"],), ["example.com"],),
self._call(csrfile, data)) self._call(csrfile, data))
+4 -4
View File
@@ -43,20 +43,20 @@ class GetEmailTest(unittest.TestCase):
def test_ok_safe(self): def test_ok_safe(self):
self.input.return_value = (display_util.OK, "foo@bar.baz") self.input.return_value = (display_util.OK, "foo@bar.baz")
with mock.patch("certbot.display.ops.le_util.safe_email") as mock_safe_email: with mock.patch("certbot.display.ops.util.safe_email") as mock_safe_email:
mock_safe_email.return_value = True mock_safe_email.return_value = True
self.assertTrue(self._call() is "foo@bar.baz") self.assertTrue(self._call() is "foo@bar.baz")
def test_ok_not_safe(self): def test_ok_not_safe(self):
self.input.return_value = (display_util.OK, "foo@bar.baz") self.input.return_value = (display_util.OK, "foo@bar.baz")
with mock.patch("certbot.display.ops.le_util.safe_email") as mock_safe_email: with mock.patch("certbot.display.ops.util.safe_email") as mock_safe_email:
mock_safe_email.side_effect = [False, True] mock_safe_email.side_effect = [False, True]
self.assertTrue(self._call() is "foo@bar.baz") self.assertTrue(self._call() is "foo@bar.baz")
def test_invalid_flag(self): def test_invalid_flag(self):
invalid_txt = "There seem to be problems" invalid_txt = "There seem to be problems"
self.input.return_value = (display_util.OK, "foo@bar.baz") self.input.return_value = (display_util.OK, "foo@bar.baz")
with mock.patch("certbot.display.ops.le_util.safe_email") as mock_safe_email: with mock.patch("certbot.display.ops.util.safe_email") as mock_safe_email:
mock_safe_email.return_value = True mock_safe_email.return_value = True
self._call() self._call()
self.assertTrue(invalid_txt not in self.input.call_args[0][0]) self.assertTrue(invalid_txt not in self.input.call_args[0][0])
@@ -65,7 +65,7 @@ class GetEmailTest(unittest.TestCase):
def test_optional_flag(self): def test_optional_flag(self):
self.input.return_value = (display_util.OK, "foo@bar.baz") self.input.return_value = (display_util.OK, "foo@bar.baz")
with mock.patch("certbot.display.ops.le_util.safe_email") as mock_safe_email: with mock.patch("certbot.display.ops.util.safe_email") as mock_safe_email:
mock_safe_email.side_effect = [False, True] mock_safe_email.side_effect = [False, True]
self._call(optional=False) self._call(optional=False)
for call in self.input.call_args_list: for call in self.input.call_args_list:
+1 -1
View File
@@ -164,7 +164,7 @@ class ReverterCheckpointLocalTest(unittest.TestCase):
errors.ReverterError, self.reverter.register_undo_command, errors.ReverterError, self.reverter.register_undo_command,
True, ["command"]) True, ["command"])
@mock.patch("certbot.le_util.run_script") @mock.patch("certbot.util.run_script")
def test_run_undo_commands(self, mock_run): def test_run_undo_commands(self, mock_run):
mock_run.side_effect = ["", errors.SubprocessError] mock_run.side_effect = ["", errors.SubprocessError]
coms = [ coms = [
+1 -1
View File
@@ -682,7 +682,7 @@ class RenewableCertTests(BaseRenewableCertTest):
self.assertTrue(os.path.exists(os.path.join( self.assertTrue(os.path.exists(os.path.join(
self.cli_config.archive_dir, "the-lineage.com", "privkey1.pem"))) self.cli_config.archive_dir, "the-lineage.com", "privkey1.pem")))
@mock.patch("certbot.storage.le_util.unique_lineage_name") @mock.patch("certbot.storage.util.unique_lineage_name")
def test_invalid_config_filename(self, mock_uln): def test_invalid_config_filename(self, mock_uln):
from certbot import storage from certbot import storage
mock_uln.return_value = "this_does_not_end_with_dot_conf", "yikes" mock_uln.return_value = "this_does_not_end_with_dot_conf", "yikes"
+7
View File
@@ -0,0 +1,7 @@
NAME="SystemdOS"
VERSION="42.42.42 LTS, Unreal"
ID=systemdos
ID_LIKE=debian
VERSION_ID="42"
HOME_URL="http://www.example.com/"
SUPPORT_URL="http://help.example.com/"
@@ -1,4 +1,4 @@
"""Tests for certbot.le_util.""" """Tests for certbot.util."""
import argparse import argparse
import errno import errno
import os import os
@@ -10,18 +10,18 @@ import unittest
import mock import mock
import six import six
import certbot
from certbot import errors from certbot import errors
from certbot.tests import test_util
class RunScriptTest(unittest.TestCase): class RunScriptTest(unittest.TestCase):
"""Tests for certbot.le_util.run_script.""" """Tests for certbot.util.run_script."""
@classmethod @classmethod
def _call(cls, params): def _call(cls, params):
from certbot.le_util import run_script from certbot.util import run_script
return run_script(params) return run_script(params)
@mock.patch("certbot.le_util.subprocess.Popen") @mock.patch("certbot.util.subprocess.Popen")
def test_default(self, mock_popen): def test_default(self, mock_popen):
"""These will be changed soon enough with reload.""" """These will be changed soon enough with reload."""
mock_popen().returncode = 0 mock_popen().returncode = 0
@@ -31,13 +31,13 @@ class RunScriptTest(unittest.TestCase):
self.assertEqual(out, "stdout") self.assertEqual(out, "stdout")
self.assertEqual(err, "stderr") self.assertEqual(err, "stderr")
@mock.patch("certbot.le_util.subprocess.Popen") @mock.patch("certbot.util.subprocess.Popen")
def test_bad_process(self, mock_popen): def test_bad_process(self, mock_popen):
mock_popen.side_effect = OSError mock_popen.side_effect = OSError
self.assertRaises(errors.SubprocessError, self._call, ["test"]) self.assertRaises(errors.SubprocessError, self._call, ["test"])
@mock.patch("certbot.le_util.subprocess.Popen") @mock.patch("certbot.util.subprocess.Popen")
def test_failure(self, mock_popen): def test_failure(self, mock_popen):
mock_popen().communicate.return_value = ("", "") mock_popen().communicate.return_value = ("", "")
mock_popen().returncode = 1 mock_popen().returncode = 1
@@ -46,29 +46,29 @@ class RunScriptTest(unittest.TestCase):
class ExeExistsTest(unittest.TestCase): class ExeExistsTest(unittest.TestCase):
"""Tests for certbot.le_util.exe_exists.""" """Tests for certbot.util.exe_exists."""
@classmethod @classmethod
def _call(cls, exe): def _call(cls, exe):
from certbot.le_util import exe_exists from certbot.util import exe_exists
return exe_exists(exe) return exe_exists(exe)
@mock.patch("certbot.le_util.os.path.isfile") @mock.patch("certbot.util.os.path.isfile")
@mock.patch("certbot.le_util.os.access") @mock.patch("certbot.util.os.access")
def test_full_path(self, mock_access, mock_isfile): def test_full_path(self, mock_access, mock_isfile):
mock_access.return_value = True mock_access.return_value = True
mock_isfile.return_value = True mock_isfile.return_value = True
self.assertTrue(self._call("/path/to/exe")) self.assertTrue(self._call("/path/to/exe"))
@mock.patch("certbot.le_util.os.path.isfile") @mock.patch("certbot.util.os.path.isfile")
@mock.patch("certbot.le_util.os.access") @mock.patch("certbot.util.os.access")
def test_on_path(self, mock_access, mock_isfile): def test_on_path(self, mock_access, mock_isfile):
mock_access.return_value = True mock_access.return_value = True
mock_isfile.return_value = True mock_isfile.return_value = True
self.assertTrue(self._call("exe")) self.assertTrue(self._call("exe"))
@mock.patch("certbot.le_util.os.path.isfile") @mock.patch("certbot.util.os.path.isfile")
@mock.patch("certbot.le_util.os.access") @mock.patch("certbot.util.os.access")
def test_not_found(self, mock_access, mock_isfile): def test_not_found(self, mock_access, mock_isfile):
mock_access.return_value = False mock_access.return_value = False
mock_isfile.return_value = True mock_isfile.return_value = True
@@ -76,7 +76,7 @@ class ExeExistsTest(unittest.TestCase):
class MakeOrVerifyDirTest(unittest.TestCase): class MakeOrVerifyDirTest(unittest.TestCase):
"""Tests for certbot.le_util.make_or_verify_dir. """Tests for certbot.util.make_or_verify_dir.
Note that it is not possible to test for a wrong directory owner, Note that it is not possible to test for a wrong directory owner,
as this testing script would have to be run as root. as this testing script would have to be run as root.
@@ -94,7 +94,7 @@ class MakeOrVerifyDirTest(unittest.TestCase):
shutil.rmtree(self.root_path, ignore_errors=True) shutil.rmtree(self.root_path, ignore_errors=True)
def _call(self, directory, mode): def _call(self, directory, mode):
from certbot.le_util import make_or_verify_dir from certbot.util import make_or_verify_dir
return make_or_verify_dir(directory, mode, self.uid, strict=True) return make_or_verify_dir(directory, mode, self.uid, strict=True)
def test_creates_dir_when_missing(self): def test_creates_dir_when_missing(self):
@@ -117,7 +117,7 @@ class MakeOrVerifyDirTest(unittest.TestCase):
class CheckPermissionsTest(unittest.TestCase): class CheckPermissionsTest(unittest.TestCase):
"""Tests for certbot.le_util.check_permissions. """Tests for certbot.util.check_permissions.
Note that it is not possible to test for a wrong file owner, Note that it is not possible to test for a wrong file owner,
as this testing script would have to be run as root. as this testing script would have to be run as root.
@@ -132,7 +132,7 @@ class CheckPermissionsTest(unittest.TestCase):
os.remove(self.path) os.remove(self.path)
def _call(self, mode): def _call(self, mode):
from certbot.le_util import check_permissions from certbot.util import check_permissions
return check_permissions(self.path, mode, self.uid) return check_permissions(self.path, mode, self.uid)
def test_ok_mode(self): def test_ok_mode(self):
@@ -145,7 +145,7 @@ class CheckPermissionsTest(unittest.TestCase):
class UniqueFileTest(unittest.TestCase): class UniqueFileTest(unittest.TestCase):
"""Tests for certbot.le_util.unique_file.""" """Tests for certbot.util.unique_file."""
def setUp(self): def setUp(self):
self.root_path = tempfile.mkdtemp() self.root_path = tempfile.mkdtemp()
@@ -155,7 +155,7 @@ class UniqueFileTest(unittest.TestCase):
shutil.rmtree(self.root_path, ignore_errors=True) shutil.rmtree(self.root_path, ignore_errors=True)
def _call(self, mode=0o600): def _call(self, mode=0o600):
from certbot.le_util import unique_file from certbot.util import unique_file
return unique_file(self.default_name, mode) return unique_file(self.default_name, mode)
def test_returns_fd_for_writing(self): def test_returns_fd_for_writing(self):
@@ -190,7 +190,7 @@ class UniqueFileTest(unittest.TestCase):
class UniqueLineageNameTest(unittest.TestCase): class UniqueLineageNameTest(unittest.TestCase):
"""Tests for certbot.le_util.unique_lineage_name.""" """Tests for certbot.util.unique_lineage_name."""
def setUp(self): def setUp(self):
self.root_path = tempfile.mkdtemp() self.root_path = tempfile.mkdtemp()
@@ -199,7 +199,7 @@ class UniqueLineageNameTest(unittest.TestCase):
shutil.rmtree(self.root_path, ignore_errors=True) shutil.rmtree(self.root_path, ignore_errors=True)
def _call(self, filename, mode=0o777): def _call(self, filename, mode=0o777):
from certbot.le_util import unique_lineage_name from certbot.util import unique_lineage_name
return unique_lineage_name(self.root_path, filename, mode) return unique_lineage_name(self.root_path, filename, mode)
def test_basic(self): def test_basic(self):
@@ -214,14 +214,14 @@ class UniqueLineageNameTest(unittest.TestCase):
self.assertTrue(isinstance(name, str)) self.assertTrue(isinstance(name, str))
self.assertTrue("wow-0009.conf" in name) self.assertTrue("wow-0009.conf" in name)
@mock.patch("certbot.le_util.os.fdopen") @mock.patch("certbot.util.os.fdopen")
def test_failure(self, mock_fdopen): def test_failure(self, mock_fdopen):
err = OSError("whoops") err = OSError("whoops")
err.errno = errno.EIO err.errno = errno.EIO
mock_fdopen.side_effect = err mock_fdopen.side_effect = err
self.assertRaises(OSError, self._call, "wow") self.assertRaises(OSError, self._call, "wow")
@mock.patch("certbot.le_util.os.fdopen") @mock.patch("certbot.util.os.fdopen")
def test_subsequent_failure(self, mock_fdopen): def test_subsequent_failure(self, mock_fdopen):
self._call("wow") self._call("wow")
err = OSError("whoops") err = OSError("whoops")
@@ -231,7 +231,7 @@ class UniqueLineageNameTest(unittest.TestCase):
class SafelyRemoveTest(unittest.TestCase): class SafelyRemoveTest(unittest.TestCase):
"""Tests for certbot.le_util.safely_remove.""" """Tests for certbot.util.safely_remove."""
def setUp(self): def setUp(self):
self.tmp = tempfile.mkdtemp() self.tmp = tempfile.mkdtemp()
@@ -241,7 +241,7 @@ class SafelyRemoveTest(unittest.TestCase):
shutil.rmtree(self.tmp) shutil.rmtree(self.tmp)
def _call(self): def _call(self):
from certbot.le_util import safely_remove from certbot.util import safely_remove
return safely_remove(self.path) return safely_remove(self.path)
def test_exists(self): def test_exists(self):
@@ -255,7 +255,7 @@ class SafelyRemoveTest(unittest.TestCase):
# no error, yay! # no error, yay!
self.assertFalse(os.path.exists(self.path)) self.assertFalse(os.path.exists(self.path))
@mock.patch("certbot.le_util.os.remove") @mock.patch("certbot.util.os.remove")
def test_other_error_passthrough(self, mock_remove): def test_other_error_passthrough(self, mock_remove):
mock_remove.side_effect = OSError mock_remove.side_effect = OSError
self.assertRaises(OSError, self._call) self.assertRaises(OSError, self._call)
@@ -265,7 +265,7 @@ class SafeEmailTest(unittest.TestCase):
"""Test safe_email.""" """Test safe_email."""
@classmethod @classmethod
def _call(cls, addr): def _call(cls, addr):
from certbot.le_util import safe_email from certbot.util import safe_email
return safe_email(addr) return safe_email(addr)
def test_valid_emails(self): def test_valid_emails(self):
@@ -293,7 +293,7 @@ class AddDeprecatedArgumentTest(unittest.TestCase):
self.parser = argparse.ArgumentParser() self.parser = argparse.ArgumentParser()
def _call(self, argument_name, nargs): def _call(self, argument_name, nargs):
from certbot.le_util import add_deprecated_argument from certbot.util import add_deprecated_argument
add_deprecated_argument(self.parser.add_argument, argument_name, nargs) add_deprecated_argument(self.parser.add_argument, argument_name, nargs)
@@ -309,14 +309,14 @@ class AddDeprecatedArgumentTest(unittest.TestCase):
def _get_argparse_warnings(self, args): def _get_argparse_warnings(self, args):
stderr = six.StringIO() stderr = six.StringIO()
with mock.patch("certbot.le_util.sys.stderr", new=stderr): with mock.patch("certbot.util.sys.stderr", new=stderr):
self.parser.parse_args(args) self.parser.parse_args(args)
return stderr.getvalue() return stderr.getvalue()
def test_help(self): def test_help(self):
self._call("--old-option", 2) self._call("--old-option", 2)
stdout = six.StringIO() stdout = six.StringIO()
with mock.patch("certbot.le_util.sys.stdout", new=stdout): with mock.patch("certbot.util.sys.stdout", new=stdout):
try: try:
self.parser.parse_args(["-h"]) self.parser.parse_args(["-h"])
except SystemExit: except SystemExit:
@@ -328,7 +328,7 @@ class EnforceDomainSanityTest(unittest.TestCase):
"""Test enforce_domain_sanity.""" """Test enforce_domain_sanity."""
def _call(self, domain): def _call(self, domain):
from certbot.le_util import enforce_domain_sanity from certbot.util import enforce_domain_sanity
return enforce_domain_sanity(domain) return enforce_domain_sanity(domain)
def test_nonascii_str(self): def test_nonascii_str(self):
@@ -340,31 +340,66 @@ class EnforceDomainSanityTest(unittest.TestCase):
u"eichh\u00f6rnchen.example.com") u"eichh\u00f6rnchen.example.com")
class GetStrictVersionTest(unittest.TestCase): class OsInfoTest(unittest.TestCase):
"""Tests for certbot.le_util.get_strict_version.""" """Test OS / distribution detection"""
@classmethod def test_systemd_os_release(self):
def _call(cls, *args, **kwargs): from certbot.util import (get_os_info, get_systemd_os_info,
from certbot.le_util import get_strict_version get_os_info_ua)
return get_strict_version(*args, **kwargs)
def test_two_dev_versions(self): with mock.patch('os.path.isfile', return_value=True):
self.assertTrue( self.assertEqual(get_os_info(
self._call("0.0.0.dev20151006") < self._call("0.0.0.dev20151008")) test_util.vector_path("os-release"))[0], 'systemdos')
self.assertEqual(get_os_info(
test_util.vector_path("os-release"))[1], '42')
self.assertEqual(get_systemd_os_info("/dev/null"), ("", ""))
self.assertEqual(get_os_info_ua(
test_util.vector_path("os-release")),
"SystemdOS")
with mock.patch('os.path.isfile', return_value=False):
self.assertEqual(get_systemd_os_info(), ("", ""))
def test_one_dev_one_release_version(self): @mock.patch("certbot.util.subprocess.Popen")
self.assertTrue(self._call("1.0.0.dev0") < self._call("1.0.0")) def test_non_systemd_os_info(self, popen_mock):
self.assertTrue(self._call("1.0.0") < self._call("1.0.1.dev0")) from certbot.util import (get_os_info, get_python_os_info,
get_os_info_ua)
with mock.patch('os.path.isfile', return_value=False):
with mock.patch('platform.system_alias',
return_value=('NonSystemD', '42', '42')):
self.assertEqual(get_os_info()[0], 'nonsystemd')
self.assertEqual(get_os_info_ua(),
" ".join(get_python_os_info()))
def test_two_release_versions(self): with mock.patch('platform.system_alias',
self.assertTrue(self._call("0.0.0") < self._call("0.0.1")) return_value=('darwin', '', '')):
self.assertTrue(self._call("0.0.0") < self._call("0.1.0")) comm_mock = mock.Mock()
self.assertTrue(self._call("0.0.0") < self._call("1.0.0")) comm_attrs = {'communicate.return_value':
('42.42.42', 'error')}
comm_mock.configure_mock(**comm_attrs) # pylint: disable=star-args
popen_mock.return_value = comm_mock
self.assertEqual(get_os_info()[0], 'darwin')
self.assertEqual(get_os_info()[1], '42.42.42')
def test_current_version(self): with mock.patch('platform.system_alias',
current_version = self._call(certbot.__version__) return_value=('linux', '', '')):
self.assertTrue(self._call("0.6.0") < current_version) with mock.patch('platform.linux_distribution',
self.assertTrue(current_version < self._call("99.99.99")) return_value=('', '', '')):
self.assertEqual(get_python_os_info(), ("linux", ""))
with mock.patch('platform.linux_distribution',
return_value=('testdist', '42', '')):
self.assertEqual(get_python_os_info(), ("testdist", "42"))
with mock.patch('platform.system_alias',
return_value=('freebsd', '9.3-RC3-p1', '')):
self.assertEqual(get_python_os_info(), ("freebsd", "9"))
with mock.patch('platform.system_alias',
return_value=('windows', '', '')):
with mock.patch('platform.win32_ver',
return_value=('4242', '95', '2', '')):
self.assertEqual(get_python_os_info(),
("windows", "95"))
if __name__ == "__main__": if __name__ == "__main__":
+90 -4
View File
@@ -213,9 +213,95 @@ def safely_remove(path):
raise raise
def get_os_info(): def get_os_info(filepath="/etc/os-release"):
"""
Get OS name and version
:param str filepath: File path of os-release file
:returns: (os_name, os_version)
:rtype: `tuple` of `str`
"""
if os.path.isfile(filepath):
# Systemd os-release parsing might be viable
os_name, os_version = get_systemd_os_info(filepath=filepath)
if os_name:
return (os_name, os_version)
# Fallback to platform module
return get_python_os_info()
def get_os_info_ua(filepath="/etc/os-release"):
"""
Get OS name and version string for User Agent
:param str filepath: File path of os-release file
:returns: os_ua
:rtype: `str`
"""
if os.path.isfile(filepath):
os_ua = _get_systemd_os_release_var("PRETTY_NAME", filepath=filepath)
if not os_ua:
os_ua = _get_systemd_os_release_var("NAME", filepath=filepath)
if os_ua:
return os_ua
# Fallback
return " ".join(get_python_os_info())
def get_systemd_os_info(filepath="/etc/os-release"):
"""
Parse systemd /etc/os-release for distribution information
:param str filepath: File path of os-release file
:returns: (os_name, os_version)
:rtype: `tuple` of `str`
"""
os_name = _get_systemd_os_release_var("ID", filepath=filepath)
os_version = _get_systemd_os_release_var("VERSION_ID", filepath=filepath)
return (os_name, os_version)
def _get_systemd_os_release_var(varname, filepath="/etc/os-release"):
"""
Get single value from systemd /etc/os-release
:param str varname: Name of variable to fetch
:param str filepath: File path of os-release file
:returns: requested value
:rtype: `str`
"""
var_string = varname+"="
if not os.path.isfile(filepath):
return ""
with open(filepath, 'r') as fh:
contents = fh.readlines()
for line in contents:
if line.strip().startswith(var_string):
# Return the value of var, normalized
return _normalize_string(line.strip()[len(var_string):])
return ""
def _normalize_string(orig):
"""
Helper function for _get_systemd_os_release_var() to remove quotes
and whitespaces
"""
return orig.replace('"', '').replace("'", "").strip()
def get_python_os_info():
""" """
Get Operating System type/distribution and major version Get Operating System type/distribution and major version
using python platform module
:returns: (os_name, os_version) :returns: (os_name, os_version)
:rtype: `tuple` of `str` :rtype: `tuple` of `str`
@@ -240,7 +326,6 @@ def get_os_info():
["sw_vers", "-productVersion"], ["sw_vers", "-productVersion"],
stdout=subprocess.PIPE stdout=subprocess.PIPE
).communicate()[0] ).communicate()[0]
os_ver = os_ver.partition(".")[0]
elif os_type.startswith('freebsd'): elif os_type.startswith('freebsd'):
# eg "9.3-RC3-p1" # eg "9.3-RC3-p1"
os_ver = os_ver.partition("-")[0] os_ver = os_ver.partition("-")[0]
@@ -317,7 +402,7 @@ def enforce_domain_sanity(domain):
domain = domain.encode('ascii').lower() domain = domain.encode('ascii').lower()
except UnicodeError: except UnicodeError:
error_fmt = (u"Internationalized domain names " error_fmt = (u"Internationalized domain names "
"are not presently supported: {0}") "are not presently supported: {0}")
if isinstance(domain, six.text_type): if isinstance(domain, six.text_type):
raise errors.ConfigurationError(error_fmt.format(domain)) raise errors.ConfigurationError(error_fmt.format(domain))
else: else:
@@ -344,7 +429,8 @@ def enforce_domain_sanity(domain):
# first and last char is not "-" # first and last char is not "-"
fqdn = re.compile("^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,63}$") fqdn = re.compile("^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,63}$")
if not fqdn.match(domain): if not fqdn.match(domain):
raise errors.ConfigurationError("Requested domain {0} is not a FQDN".format(domain)) raise errors.ConfigurationError("Requested domain {0} is not a FQDN"
.format(domain))
return domain return domain
-5
View File
@@ -1,5 +0,0 @@
:mod:`certbot.le_util`
--------------------------
.. automodule:: certbot.le_util
:members:
+5
View File
@@ -0,0 +1,5 @@
:mod:`certbot.util`
--------------------------
.. automodule:: certbot.util
:members:
+22 -10
View File
@@ -28,6 +28,7 @@ optional arguments:
require additional command line flags; the client will require additional command line flags; the client will
try to explain which ones are required if it finds one try to explain which ones are required if it finds one
missing (default: False) missing (default: False)
--dialog Run using dialog (default: False)
--dry-run Perform a test run of the client, obtaining test --dry-run Perform a test run of the client, obtaining test
(invalid) certs but not saving them to disk. This can (invalid) certs but not saving them to disk. This can
currently only be used with the 'certonly' and 'renew' currently only be used with the 'certonly' and 'renew'
@@ -130,6 +131,10 @@ security:
Security parameters & server settings Security parameters & server settings
--rsa-key-size N Size of the RSA key. (default: 2048) --rsa-key-size N Size of the RSA key. (default: 2048)
--must-staple Adds the OCSP Must Staple extension to the
certificate. Autoconfigures OCSP Stapling for
supported setups (Apache version >= 2.3.3 ). (default:
False)
--redirect Automatically redirect all HTTP traffic to HTTPS for --redirect Automatically redirect all HTTP traffic to HTTPS for
the newly authenticated vhost. (default: None) the newly authenticated vhost. (default: None)
--no-redirect Do not automatically redirect all HTTP traffic to --no-redirect Do not automatically redirect all HTTP traffic to
@@ -148,6 +153,11 @@ security:
--no-uir Do not automatically set the "Content-Security-Policy: --no-uir Do not automatically set the "Content-Security-Policy:
upgrade-insecure-requests" header to every HTTP upgrade-insecure-requests" header to every HTTP
response. (default: None) response. (default: None)
--staple-ocsp Enables OCSP Stapling. A valid OCSP response is
stapled to the certificate that the server offers
during TLS. (default: None)
--no-staple-ocsp Do not automatically enable OCSP Stapling. (default:
None)
--strict-permissions Require that all configuration files are owned by the --strict-permissions Require that all configuration files are owned by the
current user; only needed if your config is somewhere current user; only needed if your config is somewhere
unsafe like /tmp/ (default: False) unsafe like /tmp/ (default: False)
@@ -173,7 +183,9 @@ renew:
Command to be run in a shell after attempting to Command to be run in a shell after attempting to
obtain/renew certificates. Can be used to deploy obtain/renew certificates. Can be used to deploy
renewed certificates, or to restart any servers that renewed certificates, or to restart any servers that
were stopped by --pre-hook. (default: None) were stopped by --pre-hook. This is only run if an
attempt was made to obtain/renew a certificate.
(default: None)
--renew-hook RENEW_HOOK --renew-hook RENEW_HOOK
Command to be run in a shell once for each Command to be run in a shell once for each
successfully renewed certificate.For this command, the successfully renewed certificate.For this command, the
@@ -263,15 +275,6 @@ plugins:
--webroot Obtain certs by placing files in a webroot directory. --webroot Obtain certs by placing files in a webroot directory.
(default: False) (default: False)
nginx:
Nginx Web Server - currently doesn't work
--nginx-server-root NGINX_SERVER_ROOT
Nginx server root directory. (default: /etc/nginx)
--nginx-ctl NGINX_CTL
Path to the 'nginx' binary, used for 'configtest' and
retrieving nginx version number. (default: nginx)
standalone: standalone:
Automatically use a temporary webserver Automatically use a temporary webserver
@@ -288,6 +291,15 @@ manual:
Automatically allows public IP logging. (default: Automatically allows public IP logging. (default:
False) False)
nginx:
Nginx Web Server - currently doesn't work
--nginx-server-root NGINX_SERVER_ROOT
Nginx server root directory. (default: /etc/nginx)
--nginx-ctl NGINX_CTL
Path to the 'nginx' binary, used for 'configtest' and
retrieving nginx version number. (default: nginx)
webroot: webroot:
Place files in webroot directory Place files in webroot directory
+1 -1
View File
@@ -16,7 +16,7 @@ here = os.path.abspath(os.path.dirname(__file__))
readme = read_file(os.path.join(here, 'README.rst')) readme = read_file(os.path.join(here, 'README.rst'))
version = '0.7.0.dev0' version = '0.8.0.dev0'
# This package is a simple shim around certbot-apache # This package is a simple shim around certbot-apache
+54 -45
View File
@@ -19,7 +19,7 @@ XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share}
VENV_NAME="letsencrypt" VENV_NAME="letsencrypt"
VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"}
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
LE_AUTO_VERSION="0.6.0" LE_AUTO_VERSION="0.7.0"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -38,17 +38,6 @@ Help for certbot itself cannot be provided until it is installed.
All arguments are accepted and forwarded to the Certbot client when run." All arguments are accepted and forwarded to the Certbot client when run."
while getopts ":hnv" arg; do
case $arg in
h)
HELP=1;;
n)
ASSUME_YES=1;;
v)
VERBOSE=1;;
esac
done
for arg in "$@" ; do for arg in "$@" ; do
case "$arg" in case "$arg" in
--debug) --debug)
@@ -65,9 +54,26 @@ for arg in "$@" ; do
ASSUME_YES=1;; ASSUME_YES=1;;
--verbose) --verbose)
VERBOSE=1;; VERBOSE=1;;
-[!-]*)
while getopts ":hnv" short_arg $arg; do
case "$short_arg" in
h)
HELP=1;;
n)
ASSUME_YES=1;;
v)
VERBOSE=1;;
esac
done;;
esac esac
done done
if [ $BASENAME = "letsencrypt-auto" ]; then
# letsencrypt-auto does not respect --help or --yes for backwards compatibility
ASSUME_YES=1
HELP=0
fi
# certbot-auto needs root access to bootstrap OS dependencies, and # certbot-auto needs root access to bootstrap OS dependencies, and
# certbot itself needs root access for almost all modes of operation # certbot itself needs root access for almost all modes of operation
# The "normal" case is that sudo is used for the steps that need root, but # The "normal" case is that sudo is used for the steps that need root, but
@@ -107,12 +113,6 @@ else
SUDO= SUDO=
fi fi
if [ $BASENAME = "letsencrypt-auto" ]; then
# letsencrypt-auto does not respect --help or --yes for backwards compatibility
ASSUME_YES=1
HELP=0
fi
ExperimentalBootstrap() { ExperimentalBootstrap() {
# Arguments: Platform name, bootstrap function name # Arguments: Platform name, bootstrap function name
if [ "$DEBUG" = 1 ]; then if [ "$DEBUG" = 1 ]; then
@@ -425,7 +425,8 @@ BootstrapMac() {
$pkgcmd augeas $pkgcmd augeas
$pkgcmd dialog $pkgcmd dialog
if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" ]; then if [ "$(which python)" = "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" \
-o "$(which python)" = "/usr/bin/python" ]; then
# We want to avoid using the system Python because it requires root to use pip. # We want to avoid using the system Python because it requires root to use pip.
# python.org, MacPorts or HomeBrew Python installations should all be OK. # python.org, MacPorts or HomeBrew Python installations should all be OK.
echo "Installing python..." echo "Installing python..."
@@ -435,7 +436,8 @@ BootstrapMac() {
# Workaround for _dlopen not finding augeas on OS X # Workaround for _dlopen not finding augeas on OS X
if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then if [ "$pkgman" = "port" ] && ! [ -e "/usr/local/lib/libaugeas.dylib" ] && [ -e "/opt/local/lib/libaugeas.dylib" ]; then
echo "Applying augeas workaround" echo "Applying augeas workaround"
$SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib $SUDO mkdir -p /usr/local/lib/
$SUDO ln -s /opt/local/lib/libaugeas.dylib /usr/local/lib/
fi fi
if ! hash pip 2>/dev/null; then if ! hash pip 2>/dev/null; then
@@ -451,6 +453,11 @@ BootstrapMac() {
fi fi
} }
BootstrapSmartOS() {
pkgin update
pkgin -y install 'gcc49' 'py27-augeas' 'py27-virtualenv'
}
# Install required OS packages: # Install required OS packages:
Bootstrap() { Bootstrap() {
@@ -483,8 +490,10 @@ Bootstrap() {
ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd
elif uname | grep -iq Darwin ; then elif uname | grep -iq Darwin ; then
ExperimentalBootstrap "Mac OS X" BootstrapMac ExperimentalBootstrap "Mac OS X" BootstrapMac
elif grep -iq "Amazon Linux" /etc/issue ; then elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
ExperimentalBootstrap "Joyent SmartOS Zone" BootstrapSmartOS
else else
echo "Sorry, I don't know how to bootstrap Certbot on your operating system!" echo "Sorry, I don't know how to bootstrap Certbot on your operating system!"
echo echo
@@ -523,6 +532,7 @@ if [ "$1" = "--le-auto-phase2" ]; then
echo "Installing Python packages..." echo "Installing Python packages..."
TEMP_DIR=$(TempDir) TEMP_DIR=$(TempDir)
trap 'rm -rf "$TEMP_DIR"' EXIT
# There is no $ interpolation due to quotes on starting heredoc delimiter. # There is no $ interpolation due to quotes on starting heredoc delimiter.
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt" cat << "UNLIKELY_EOF" > "$TEMP_DIR/letsencrypt-auto-requirements.txt"
@@ -706,21 +716,21 @@ mock==1.0.1 \
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE.
acme==0.6.0 \ acme==0.7.0 \
--hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ --hash=sha256:6e61dba343806ad4cb27af84628152abc9e83a0fa24be6065587d2b46f340d7a \
--hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 --hash=sha256:9f75a1947978402026b741bdee8a18fc5a1cfd539b78e523b7e5f279bf18eeb9
certbot==0.6.0 \ certbot==0.7.0 \
--hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ --hash=sha256:55604e43d231ac226edefed8dc110d792052095c3d75ad0e4a228ae0989fe5fd \
--hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d --hash=sha256:ad5083d75e16d1ab806802d3a32f34973b6d7adaf083aee87e07a6c1359efe88
certbot-apache==0.6.0 \ certbot-apache==0.7.0 \
--hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ --hash=sha256:5ab5ed9b2af6c7db9495ce1491122798e9d0764e3df8f0843d11d89690bf7f88 \
--hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 --hash=sha256:1ddbfaf01bcb0b05c0dcc8b2ebd37637f080cf798151e8140c20c9f5fe7bae75
letsencrypt==0.6.0 \ letsencrypt==0.7.0 \
--hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
letsencrypt-apache==0.6.0 \ letsencrypt-apache==0.7.0 \
--hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ --hash=sha256:10445980a6afc810325ea22a56e269229999120848f6c0b323b00275696b5c80 \
--hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 --hash=sha256:3f4656088a18e4efea7cd7eb4965e14e8d901f3b64f4691e79cafd0bb91890f0
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@@ -880,7 +890,6 @@ UNLIKELY_EOF
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1` PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
PIP_STATUS=$? PIP_STATUS=$?
set -e set -e
rm -rf "$TEMP_DIR"
if [ "$PIP_STATUS" != 0 ]; then if [ "$PIP_STATUS" != 0 ]; then
# Report error. (Otherwise, be quiet.) # Report error. (Otherwise, be quiet.)
echo "Had a problem while installing Python packages:" echo "Had a problem while installing Python packages:"
@@ -890,14 +899,16 @@ UNLIKELY_EOF
fi fi
echo "Installation succeeded." echo "Installation succeeded."
fi fi
echo "Requesting root privileges to run certbot..." if [ -n "$SUDO" ]; then
# SUDO is su wrapper or sudo
echo "Requesting root privileges to run certbot..."
echo " $VENV_BIN/letsencrypt" "$@"
fi
if [ -z "$SUDO_ENV" ] ; then if [ -z "$SUDO_ENV" ] ; then
# SUDO is su wrapper / noop # SUDO is su wrapper / noop
echo " " $SUDO "$VENV_BIN/letsencrypt" "$@"
$SUDO "$VENV_BIN/letsencrypt" "$@" $SUDO "$VENV_BIN/letsencrypt" "$@"
else else
# sudo # sudo
echo " " $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@"
$SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@" $SUDO "$SUDO_ENV" "$VENV_BIN/letsencrypt" "$@"
fi fi
@@ -923,8 +934,8 @@ else
fi fi
if [ "$NO_SELF_UPGRADE" != 1 ]; then if [ "$NO_SELF_UPGRADE" != 1 ]; then
echo "Checking for new version..."
TEMP_DIR=$(TempDir) TEMP_DIR=$(TempDir)
trap 'rm -rf "$TEMP_DIR"' EXIT
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py" cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py"
"""Do downloading and JSON parsing without additional dependencies. :: """Do downloading and JSON parsing without additional dependencies. ::
@@ -997,7 +1008,7 @@ def latest_stable_version(get):
"""Return the latest stable release of letsencrypt.""" """Return the latest stable release of letsencrypt."""
metadata = loads(get( metadata = loads(get(
environ.get('LE_AUTO_JSON_URL', environ.get('LE_AUTO_JSON_URL',
'https://pypi.python.org/pypi/letsencrypt/json'))) 'https://pypi.python.org/pypi/certbot/json')))
# metadata['info']['version'] actually returns the latest of any kind of # metadata['info']['version'] actually returns the latest of any kind of
# release release, contrary to https://wiki.python.org/moin/PyPIJSON. # release release, contrary to https://wiki.python.org/moin/PyPIJSON.
# The regex is a sufficient regex for picking out prereleases for most # The regex is a sufficient regex for picking out prereleases for most
@@ -1016,7 +1027,7 @@ def verified_new_le_auto(get, tag, temp_dir):
""" """
le_auto_dir = environ.get( le_auto_dir = environ.get(
'LE_AUTO_DIR_TEMPLATE', 'LE_AUTO_DIR_TEMPLATE',
'https://raw.githubusercontent.com/letsencrypt/letsencrypt/%s/' 'https://raw.githubusercontent.com/certbot/certbot/%s/'
'letsencrypt-auto-source/') % tag 'letsencrypt-auto-source/') % tag
write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto') write(get(le_auto_dir + 'letsencrypt-auto'), temp_dir, 'letsencrypt-auto')
write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig') write(get(le_auto_dir + 'letsencrypt-auto.sig'), temp_dir, 'letsencrypt-auto.sig')
@@ -1079,8 +1090,6 @@ UNLIKELY_EOF
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the # filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
# cp is unlikely to fail (esp. under sudo) if the rm doesn't. # cp is unlikely to fail (esp. under sudo) if the rm doesn't.
$SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" $SUDO mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
# TODO: Clean up temp dir safely, even if it has quotes in its path.
rm -rf "$TEMP_DIR"
fi # A newer version is available. fi # A newer version is available.
fi # Self-upgrading is allowed. fi # Self-upgrading is allowed.
+7 -7
View File
@@ -1,11 +1,11 @@
-----BEGIN PGP SIGNATURE----- -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 Version: GnuPG v1
iQEcBAABAgAGBQJXM9ZDAAoJEE0XyZXNl3XyzGkH/2KeR0jYxXKlvwfCkxU6hSC0 iQEcBAABAgAGBQJXSK5DAAoJEE0XyZXNl3Xyyb4H/Ahy9/8ADDaN5V/O/6kl6gE5
eXcxZVQk59hCSvkNGE6Mj6rwQcyjSqmRp14MaJpq7NZADN6F+HWb6VB/Wq6moMQs amQfm8T10EUD8APnNWYrYKBYruDBVvH0KiEcuAEs7q4xE5BaQatlobSnsHfv4AWW
PJtthqwhF767Qg+Py9Hp6XmlKscjXB6AKCVxq5TBwEIOTtj0rhQRLF9/+GW6jFuf TwInk2lRxYZ++MwwQf3DrqMK5QKfcoVnViZsRpZ8gHMLzsJllRm7R5eaTewO2ViM
kT6aUcDWNjOyWWUtp9vOVprDtegrltp0/2DNitlvPu263pKC+7I3GyLTq4fKP4EE KM+yDB3UsquLUvE4d3/hgBl2mXAUwsxLeFreZayvpoTcX2ARnzbtKqMaIBYDYWcx
auZSAhFry9SNR3Usf2wD3kzhvLSrT3h9Yh5oA04oaX9H6e86EHwt6RJJRHpg8s6b DewWtDsPrhKFpb2DY06S6JLmEttysUgv+hbKlaVO0yZ8cCUehkzBIGYoeS4chOLq
e0CBIIuaRJEmdiMUWlV/gAfH6M2PbG1wtJdxc0ThNEoWAjTsopr61BoHJ3cpCy4= fonNCzB8u3RtnLEFiPIy0N+A592jbLsqqUkxjammaJq3lH7nitduMLnpvGKt4yc=
=+e7/ =ex1J
-----END PGP SIGNATURE----- -----END PGP SIGNATURE-----
+16 -16
View File
@@ -19,7 +19,7 @@ XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share}
VENV_NAME="letsencrypt" VENV_NAME="letsencrypt"
VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"} VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"}
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
LE_AUTO_VERSION="0.7.0.dev0" LE_AUTO_VERSION="0.8.0.dev0"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -716,21 +716,21 @@ mock==1.0.1 \
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE.
acme==0.6.0 \ acme==0.7.0 \
--hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ --hash=sha256:6e61dba343806ad4cb27af84628152abc9e83a0fa24be6065587d2b46f340d7a \
--hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 --hash=sha256:9f75a1947978402026b741bdee8a18fc5a1cfd539b78e523b7e5f279bf18eeb9
certbot==0.6.0 \ certbot==0.7.0 \
--hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ --hash=sha256:55604e43d231ac226edefed8dc110d792052095c3d75ad0e4a228ae0989fe5fd \
--hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d --hash=sha256:ad5083d75e16d1ab806802d3a32f34973b6d7adaf083aee87e07a6c1359efe88
certbot-apache==0.6.0 \ certbot-apache==0.7.0 \
--hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ --hash=sha256:5ab5ed9b2af6c7db9495ce1491122798e9d0764e3df8f0843d11d89690bf7f88 \
--hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 --hash=sha256:1ddbfaf01bcb0b05c0dcc8b2ebd37637f080cf798151e8140c20c9f5fe7bae75
letsencrypt==0.6.0 \ letsencrypt==0.7.0 \
--hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
letsencrypt-apache==0.6.0 \ letsencrypt-apache==0.7.0 \
--hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ --hash=sha256:10445980a6afc810325ea22a56e269229999120848f6c0b323b00275696b5c80 \
--hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 --hash=sha256:3f4656088a18e4efea7cd7eb4965e14e8d901f3b64f4691e79cafd0bb91890f0
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
Binary file not shown.
@@ -178,18 +178,18 @@ mock==1.0.1 \
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE. # THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT; ADD ALL DEPENDENCIES ABOVE.
acme==0.6.0 \ acme==0.7.0 \
--hash=sha256:cbe4e7a340a19725a8740ed86e30abdbe18fc22c4c6022b7a8e56642d502bcc3 \ --hash=sha256:6e61dba343806ad4cb27af84628152abc9e83a0fa24be6065587d2b46f340d7a \
--hash=sha256:ec4e6009dfbd629b58473eb06bbebfd9fb2a79fc8831c149e9205bc38a98ecc6 --hash=sha256:9f75a1947978402026b741bdee8a18fc5a1cfd539b78e523b7e5f279bf18eeb9
certbot==0.6.0 \ certbot==0.7.0 \
--hash=sha256:a893632d228864b0a751db9f3fdd93439ed34b988ea21b64fb0f0fa2ceded6a2 \ --hash=sha256:55604e43d231ac226edefed8dc110d792052095c3d75ad0e4a228ae0989fe5fd \
--hash=sha256:80b0b7dc5afeec2816ef638a61e7c628d73cd72666eebf4984be426d1c2b492d --hash=sha256:ad5083d75e16d1ab806802d3a32f34973b6d7adaf083aee87e07a6c1359efe88
certbot-apache==0.6.0 \ certbot-apache==0.7.0 \
--hash=sha256:0ab077f0913b81ed5c1b141c3a7c4c0228ef3738d8d61a93db794d9a80718d43 \ --hash=sha256:5ab5ed9b2af6c7db9495ce1491122798e9d0764e3df8f0843d11d89690bf7f88 \
--hash=sha256:1cfbe751209079a803758f472200816fac559f2a36fdd582d25e3ba5601423a1 --hash=sha256:1ddbfaf01bcb0b05c0dcc8b2ebd37637f080cf798151e8140c20c9f5fe7bae75
letsencrypt==0.6.0 \ letsencrypt==0.7.0 \
--hash=sha256:93196c7dcd57272a753e525d145c5a9987c8968c22ec954bcf83dcc9d2499a76 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:a16d6c395f1bf5fd61a28ef83dc78f42dbecbad9d00be6236f2ad8915645c154 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
letsencrypt-apache==0.6.0 \ letsencrypt-apache==0.7.0 \
--hash=sha256:02fadc52a0796e53978c508beec9c53e1fc047660240832b9bde5d53ab3a1379 \ --hash=sha256:10445980a6afc810325ea22a56e269229999120848f6c0b323b00275696b5c80 \
--hash=sha256:1c5522d94d7750bdb9bfa6201d2c263e914f662c9d0079e673167233cf4364f1 --hash=sha256:3f4656088a18e4efea7cd7eb4965e14e8d901f3b64f4691e79cafd0bb91890f0
+4 -2
View File
@@ -11,7 +11,7 @@ from shutil import copy, rmtree
import socket import socket
import ssl import ssl
from stat import S_IRUSR, S_IXUSR from stat import S_IRUSR, S_IXUSR
from subprocess import CalledProcessError, check_output, Popen, PIPE from subprocess import CalledProcessError, Popen, PIPE
import sys import sys
from tempfile import mkdtemp from tempfile import mkdtemp
from threading import Thread from threading import Thread
@@ -146,7 +146,9 @@ def out_and_err(command, input=None, shell=False, env=None):
out, err = process.communicate(input=input) out, err = process.communicate(input=input)
status = process.poll() # same as in check_output(), though wait() sounds better status = process.poll() # same as in check_output(), though wait() sounds better
if status: if status:
raise CalledProcessError(status, command, output=out) error = CalledProcessError(status, command)
error.output = out
raise error
return out, err return out, err
+1 -1
View File
@@ -16,7 +16,7 @@ here = os.path.abspath(os.path.dirname(__file__))
readme = read_file(os.path.join(here, 'README.rst')) readme = read_file(os.path.join(here, 'README.rst'))
version = '0.7.0.dev0' version = '0.8.0.dev0'
# This package is a simple shim around certbot-nginx # This package is a simple shim around certbot-nginx
+1 -1
View File
@@ -20,7 +20,7 @@ readme = read_file(os.path.join(here, 'README.rst'))
install_requires = ['certbot'] install_requires = ['certbot']
version = '0.7.0.dev0' version = '0.8.0.dev0'
setup( setup(
+8
View File
@@ -0,0 +1,8 @@
NAME="SystemdOS"
VERSION="42.42.42 LTS, Unreal"
ID=systemdos
ID_LIKE=debian
PRETTY_NAME="SystemdOS 42.42.42 Unreal"
VERSION_ID="42"
HOME_URL="http://www.example.com/"
SUPPORT_URL="http://help.example.com/"
+3 -3
View File
@@ -45,7 +45,7 @@ export GPG_TTY=$(tty)
PORT=${PORT:-1234} PORT=${PORT:-1234}
# subpackages to be released # subpackages to be released
SUBPKGS=${SUBPKGS:-"acme certbot-apache certbot-nginx letshelp-certbot letsencrypt letsencrypt-apache letsencrypt-nginx letshelp-letsencrypt"} SUBPKGS=${SUBPKGS:-"acme certbot-apache certbot-nginx letsencrypt letsencrypt-apache letsencrypt-nginx"}
subpkgs_modules="$(echo $SUBPKGS | sed s/-/_/g)" subpkgs_modules="$(echo $SUBPKGS | sed s/-/_/g)"
# certbot_compatibility_test is not packaged because: # certbot_compatibility_test is not packaged because:
# - it is not meant to be used by anyone else than Certbot devs # - it is not meant to be used by anyone else than Certbot devs
@@ -162,13 +162,13 @@ for module in certbot $subpkgs_modules ; do
echo testing $module echo testing $module
nosetests $module nosetests $module
done done
deactivate
# pin pip hashes of the things we just built # pin pip hashes of the things we just built
for pkg in acme certbot certbot-apache letsencrypt letsencrypt-apache ; do for pkg in acme certbot certbot-apache letsencrypt letsencrypt-apache ; do
echo $pkg==$version \\ echo $pkg==$version \\
pip hash dist."$version/$pkg"/*.{whl,gz} | grep "^--hash" | python2 -c 'from sys import stdin; input = stdin.read(); print " ", input.replace("\n--hash", " \\\n --hash"),' pip hash dist."$version/$pkg"/*.{whl,gz} | grep "^--hash" | python2 -c 'from sys import stdin; input = stdin.read(); print " ", input.replace("\n--hash", " \\\n --hash"),'
done > /tmp/hashes.$$ done > /tmp/hashes.$$
deactivate
if ! wc -l /tmp/hashes.$$ | grep -qE "^\s*15 " ; then if ! wc -l /tmp/hashes.$$ | grep -qE "^\s*15 " ; then
echo Unexpected pip hash output echo Unexpected pip hash output
@@ -176,7 +176,7 @@ if ! wc -l /tmp/hashes.$$ | grep -qE "^\s*15 " ; then
fi fi
# perform hideous surgery on requirements.txt... # perform hideous surgery on requirements.txt...
head -n -9 letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt > /tmp/req.$$ head -n -15 letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt > /tmp/req.$$
cat /tmp/hashes.$$ >> /tmp/req.$$ cat /tmp/hashes.$$ >> /tmp/req.$$
cp /tmp/req.$$ letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt cp /tmp/req.$$ letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt