mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 00:35:50 +02:00
Merge branch 'master' into continuity-error
This commit is contained in:
@@ -342,6 +342,21 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
self.assoc[target_name] = vhost
|
||||
return vhost
|
||||
|
||||
def included_in_wildcard(self, names, target_name):
|
||||
"""Helper function to see if alias is covered by wildcard"""
|
||||
target_name = target_name.split(".")[::-1]
|
||||
wildcards = [domain.split(".")[1:] for domain in names if domain.startswith("*")]
|
||||
for wildcard in wildcards:
|
||||
if len(wildcard) > len(target_name):
|
||||
continue
|
||||
for idx, segment in enumerate(wildcard[::-1]):
|
||||
if segment != target_name[idx]:
|
||||
break
|
||||
else:
|
||||
# https://docs.python.org/2/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops
|
||||
return True
|
||||
return False
|
||||
|
||||
def _find_best_vhost(self, target_name):
|
||||
"""Finds the best vhost for a target_name.
|
||||
|
||||
@@ -351,16 +366,21 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
:returns: VHost or None
|
||||
|
||||
"""
|
||||
# Points 4 - Servername SSL
|
||||
# Points 3 - Address name with SSL
|
||||
# Points 2 - Servername no SSL
|
||||
# Points 6 - Servername SSL
|
||||
# Points 5 - Wildcard SSL
|
||||
# Points 4 - Address name with SSL
|
||||
# Points 3 - Servername no SSL
|
||||
# Points 2 - Wildcard no SSL
|
||||
# Points 1 - Address name with no SSL
|
||||
best_candidate = None
|
||||
best_points = 0
|
||||
for vhost in self.vhosts:
|
||||
if vhost.modmacro is True:
|
||||
continue
|
||||
if target_name in vhost.get_names():
|
||||
names = vhost.get_names()
|
||||
if target_name in names:
|
||||
points = 3
|
||||
elif self.included_in_wildcard(names, target_name):
|
||||
points = 2
|
||||
elif any(addr.get_addr() == target_name for addr in vhost.addrs):
|
||||
points = 1
|
||||
@@ -370,7 +390,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
||||
continue # pragma: no cover
|
||||
|
||||
if vhost.ssl:
|
||||
points += 2
|
||||
points += 3
|
||||
|
||||
if points > best_points:
|
||||
best_points = points
|
||||
|
||||
@@ -85,7 +85,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
mock_getutility.notification = mock.MagicMock(return_value=True)
|
||||
names = self.config.get_all_names()
|
||||
self.assertEqual(names, set(
|
||||
["letsencrypt.demo", "encryption-example.demo", "ip-172-30-0-17"]))
|
||||
["letsencrypt.demo", "encryption-example.demo", "ip-172-30-0-17", "*.blue.purple.com"]))
|
||||
|
||||
@mock.patch("zope.component.getUtility")
|
||||
@mock.patch("letsencrypt_apache.configurator.socket.gethostbyaddr")
|
||||
@@ -103,7 +103,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
self.config.vhosts.append(vhost)
|
||||
|
||||
names = self.config.get_all_names()
|
||||
self.assertEqual(len(names), 5)
|
||||
self.assertEqual(len(names), 6)
|
||||
self.assertTrue("zombo.com" in names)
|
||||
self.assertTrue("google.com" in names)
|
||||
self.assertTrue("letsencrypt.demo" in names)
|
||||
@@ -124,7 +124,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
|
||||
"""
|
||||
vhs = self.config.get_virtual_hosts()
|
||||
self.assertEqual(len(vhs), 6)
|
||||
self.assertEqual(len(vhs), 7)
|
||||
found = 0
|
||||
|
||||
for vhost in vhs:
|
||||
@@ -135,7 +135,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
else:
|
||||
raise Exception("Missed: %s" % vhost) # pragma: no cover
|
||||
|
||||
self.assertEqual(found, 6)
|
||||
self.assertEqual(found, 7)
|
||||
|
||||
# Handle case of non-debian layout get_virtual_hosts
|
||||
with mock.patch(
|
||||
@@ -143,7 +143,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
) as mock_conf:
|
||||
mock_conf.return_value = False
|
||||
vhs = self.config.get_virtual_hosts()
|
||||
self.assertEqual(len(vhs), 6)
|
||||
self.assertEqual(len(vhs), 7)
|
||||
|
||||
@mock.patch("letsencrypt_apache.display_ops.select_vhost")
|
||||
def test_choose_vhost_none_avail(self, mock_select):
|
||||
@@ -186,6 +186,20 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.config.choose_vhost, "none.com")
|
||||
|
||||
def test_choosevhost_select_vhost_with_wildcard(self):
|
||||
chosen_vhost = self.config.choose_vhost("blue.purple.com", temp=True)
|
||||
self.assertEqual(self.vh_truth[6], chosen_vhost)
|
||||
|
||||
def test_findbest_continues_on_short_domain(self):
|
||||
# pylint: disable=protected-access
|
||||
chosen_vhost = self.config._find_best_vhost("purple.com")
|
||||
self.assertEqual(None, chosen_vhost)
|
||||
|
||||
def test_findbest_continues_on_long_domain(self):
|
||||
# pylint: disable=protected-access
|
||||
chosen_vhost = self.config._find_best_vhost("green.red.purple.com")
|
||||
self.assertEqual(None, chosen_vhost)
|
||||
|
||||
def test_find_best_vhost(self):
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(
|
||||
@@ -211,6 +225,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
self.config.vhosts = [
|
||||
vh for vh in self.config.vhosts
|
||||
if vh.name not in ["letsencrypt.demo", "encryption-example.demo"]
|
||||
and "*.blue.purple.com" not in vh.aliases
|
||||
]
|
||||
|
||||
self.assertEqual(
|
||||
@@ -218,7 +233,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
|
||||
def test_non_default_vhosts(self):
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(len(self.config._non_default_vhosts()), 4)
|
||||
self.assertEqual(len(self.config._non_default_vhosts()), 5)
|
||||
|
||||
def test_is_site_enabled(self):
|
||||
"""Test if site is enabled.
|
||||
@@ -524,7 +539,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
self.assertEqual(self.config.is_name_vhost(self.vh_truth[0]),
|
||||
self.config.is_name_vhost(ssl_vhost))
|
||||
|
||||
self.assertEqual(len(self.config.vhosts), 7)
|
||||
self.assertEqual(len(self.config.vhosts), 8)
|
||||
|
||||
def test_clean_vhost_ssl(self):
|
||||
# pylint: disable=protected-access
|
||||
@@ -942,7 +957,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.config._enable_redirect(self.vh_truth[1], "")
|
||||
self.assertEqual(len(self.config.vhosts), 7)
|
||||
self.assertEqual(len(self.config.vhosts), 8)
|
||||
|
||||
def test_create_own_redirect_for_old_apache_version(self):
|
||||
self.config.parser.modules.add("rewrite_module")
|
||||
@@ -953,7 +968,7 @@ class TwoVhost80Test(util.ApacheTest):
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.config._enable_redirect(self.vh_truth[1], "")
|
||||
self.assertEqual(len(self.config.vhosts), 7)
|
||||
self.assertEqual(len(self.config.vhosts), 8)
|
||||
|
||||
def test_sift_line(self):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<VirtualHost *:80>
|
||||
|
||||
ServerName ip-172-30-0-17
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html
|
||||
ServerAlias *.blue.purple.com
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||
@@ -150,7 +150,12 @@ def get_vh_truth(temp_dir, config_name):
|
||||
os.path.join(prefix, "default-ssl-port-only.conf"),
|
||||
os.path.join(aug_pre, ("default-ssl-port-only.conf/"
|
||||
"IfModule/VirtualHost")),
|
||||
set([obj.Addr.fromstring("_default_:443")]), True, False)
|
||||
set([obj.Addr.fromstring("_default_:443")]), True, False),
|
||||
obj.VirtualHost(
|
||||
os.path.join(prefix, "wildcard.conf"),
|
||||
os.path.join(aug_pre, "wildcard.conf/VirtualHost"),
|
||||
set([obj.Addr.fromstring("*:80")]), False, False,
|
||||
"ip-172-30-0-17", aliases=["*.blue.purple.com"])
|
||||
]
|
||||
return vh_truth
|
||||
|
||||
|
||||
+120
-86
@@ -18,25 +18,31 @@ set -e # Work even if somebody does "sh thisscript.sh".
|
||||
XDG_DATA_HOME=${XDG_DATA_HOME:-~/.local/share}
|
||||
VENV_NAME="letsencrypt"
|
||||
VENV_PATH=${VENV_PATH:-"$XDG_DATA_HOME/$VENV_NAME"}
|
||||
VENV_BIN=${VENV_PATH}/bin
|
||||
LE_AUTO_VERSION="0.4.0"
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
LE_AUTO_VERSION="0.4.1"
|
||||
|
||||
# This script takes the same arguments as the main letsencrypt program, but it
|
||||
# additionally responds to --verbose (more output) and --debug (allow support
|
||||
# for experimental platforms)
|
||||
for arg in "$@" ; do
|
||||
# This first clause is redundant with the third, but hedging on portability
|
||||
if [ "$arg" = "-v" ] || [ "$arg" = "--verbose" ] || echo "$arg" | grep -E -- "-v+$" ; then
|
||||
VERBOSE=1
|
||||
elif [ "$arg" = "--no-self-upgrade" ] ; then
|
||||
# Do not upgrade this script (also prevents client upgrades, because each
|
||||
# copy of the script pins a hash of the python client)
|
||||
NO_SELF_UPGRADE=1
|
||||
elif [ "$arg" = "--os-packages-only" ] ; then
|
||||
OS_PACKAGES_ONLY=1
|
||||
elif [ "$arg" = "--debug" ]; then
|
||||
DEBUG=1
|
||||
fi
|
||||
case "$arg" in
|
||||
--debug)
|
||||
DEBUG=1;;
|
||||
--os-packages-only)
|
||||
OS_PACKAGES_ONLY=1;;
|
||||
--no-self-upgrade)
|
||||
# Do not upgrade this script (also prevents client upgrades, because each
|
||||
# copy of the script pins a hash of the python client)
|
||||
NO_SELF_UPGRADE=1;;
|
||||
--verbose)
|
||||
VERBOSE=1;;
|
||||
[!-]*|-*[!v]*|-)
|
||||
# Anything that isn't -v, -vv, etc.: that is, anything that does not
|
||||
# start with a -, contains anything that's not a v, or is just "-"
|
||||
;;
|
||||
*) # -v+ remains.
|
||||
VERBOSE=1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# letsencrypt-auto needs root access to bootstrap OS dependencies, and
|
||||
@@ -91,21 +97,18 @@ ExperimentalBootstrap() {
|
||||
}
|
||||
|
||||
DeterminePythonVersion() {
|
||||
if command -v python2.7 > /dev/null ; then
|
||||
export LE_PYTHON=${LE_PYTHON:-python2.7}
|
||||
elif command -v python27 > /dev/null ; then
|
||||
export LE_PYTHON=${LE_PYTHON:-python27}
|
||||
elif command -v python2 > /dev/null ; then
|
||||
export LE_PYTHON=${LE_PYTHON:-python2}
|
||||
elif command -v python > /dev/null ; then
|
||||
export LE_PYTHON=${LE_PYTHON:-python}
|
||||
else
|
||||
echo "Cannot find any Pythons... please install one!"
|
||||
for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do
|
||||
# Break (while keeping the LE_PYTHON value) if found.
|
||||
command -v "$LE_PYTHON" > /dev/null && break
|
||||
done
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "Cannot find any Pythons; please install one!"
|
||||
exit 1
|
||||
fi
|
||||
export LE_PYTHON
|
||||
|
||||
PYVER=`"$LE_PYTHON" --version 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'`
|
||||
if [ $PYVER -lt 26 ]; then
|
||||
PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'`
|
||||
if [ "$PYVER" -lt 26 ]; then
|
||||
echo "You have an ancient version of Python entombed in your operating system..."
|
||||
echo "This isn't going to work; you'll need at least version 2.6."
|
||||
exit 1
|
||||
@@ -165,7 +168,7 @@ BootstrapDebCommon() {
|
||||
/bin/echo '(Backports are only installed if explicitly requested via "apt-get install -t wheezy-backports")'
|
||||
fi
|
||||
|
||||
sudo sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list"
|
||||
$SUDO sh -c "echo $BACKPORT_SOURCELINE >> /etc/apt/sources.list.d/$BACKPORT_NAME.list"
|
||||
$SUDO apt-get update
|
||||
fi
|
||||
fi
|
||||
@@ -304,10 +307,11 @@ BootstrapArchCommon() {
|
||||
pkg-config
|
||||
"
|
||||
|
||||
missing=$("$SUDO" pacman -T $deps)
|
||||
# pacman -T exits with 127 if there are missing dependencies
|
||||
missing=$($SUDO pacman -T $deps) || true
|
||||
|
||||
if [ "$missing" ]; then
|
||||
"$SUDO" pacman -S --needed $missing
|
||||
$SUDO pacman -S --needed $missing
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -324,19 +328,19 @@ BootstrapGentooCommon() {
|
||||
|
||||
case "$PACKAGE_MANAGER" in
|
||||
(paludis)
|
||||
"$SUDO" cave resolve --keep-targets if-possible $PACKAGES -x
|
||||
$SUDO cave resolve --preserve-world --keep-targets if-possible $PACKAGES -x
|
||||
;;
|
||||
(pkgcore)
|
||||
"$SUDO" pmerge --noreplace $PACKAGES
|
||||
$SUDO pmerge --noreplace --oneshot $PACKAGES
|
||||
;;
|
||||
(portage|*)
|
||||
"$SUDO" emerge --noreplace $PACKAGES
|
||||
$SUDO emerge --noreplace --oneshot $PACKAGES
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
BootstrapFreeBsd() {
|
||||
"$SUDO" pkg install -Ay \
|
||||
$SUDO pkg install -Ay \
|
||||
python \
|
||||
py27-virtualenv \
|
||||
augeas \
|
||||
@@ -345,20 +349,27 @@ BootstrapFreeBsd() {
|
||||
|
||||
BootstrapMac() {
|
||||
if ! hash brew 2>/dev/null; then
|
||||
echo "Homebrew Not Installed\nDownloading..."
|
||||
echo "Homebrew not installed.\nDownloading..."
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
fi
|
||||
|
||||
brew install augeas
|
||||
brew install dialog
|
||||
if [ -z "$(brew list --versions augeas)" ]; then
|
||||
echo "augeas not installed.\nInstalling augeas from Homebrew..."
|
||||
brew install augeas
|
||||
fi
|
||||
|
||||
if ! hash pip 2>/dev/null; then
|
||||
echo "pip Not Installed\nInstalling python from Homebrew..."
|
||||
if [ -z "$(brew list --versions dialog)" ]; then
|
||||
echo "dialog not installed.\nInstalling dialog from Homebrew..."
|
||||
brew install dialog
|
||||
fi
|
||||
|
||||
if [ -z "$(brew list --versions python)" ]; then
|
||||
echo "python not installed.\nInstalling python from Homebrew..."
|
||||
brew install python
|
||||
fi
|
||||
|
||||
if ! hash virtualenv 2>/dev/null; then
|
||||
echo "virtualenv Not Installed\nInstalling with pip"
|
||||
echo "virtualenv not installed.\nInstalling with pip..."
|
||||
pip install virtualenv
|
||||
fi
|
||||
}
|
||||
@@ -412,9 +423,10 @@ TempDir() {
|
||||
|
||||
|
||||
|
||||
if [ "$NO_SELF_UPGRADE" = 1 ]; then
|
||||
if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# Phase 2: Create venv, install LE, and run.
|
||||
|
||||
shift 1 # the --le-auto-phase2 arg
|
||||
if [ -f "$VENV_BIN/letsencrypt" ]; then
|
||||
INSTALLED_VERSION=$("$VENV_BIN/letsencrypt" --version 2>&1 | cut -d " " -f 2)
|
||||
else
|
||||
@@ -609,10 +621,6 @@ traceback2==1.4.0
|
||||
# sha256: IogqDkGMKE4fcYqCKzsCKUTVPS2QjhaQsxmp0-ssBXk
|
||||
unittest2==1.1.0
|
||||
|
||||
# sha256: aUkbUwUVfDxuDwSnAZhNaud_1yn8HJrNJQd_HfOFMms
|
||||
# sha256: 619wCpv8lkILBVY1r5AC02YuQ9gMP_0x8iTCW8DV9GI
|
||||
Werkzeug==0.11.3
|
||||
|
||||
# sha256: KCwRK1XdjjyGmjVx-GdnwVCrEoSprOK97CJsWSrK-Bo
|
||||
zope.component==4.2.2
|
||||
|
||||
@@ -638,22 +646,25 @@ zope.event==4.1.0
|
||||
# sha256: sJyMHUezUxxADgGVaX8UFKYyId5u9HhZik8UYPfZo5I
|
||||
zope.interface==4.1.3
|
||||
|
||||
# sha256: ilvjjTWOS86xchl0WBZ0YOAw_0rmqdnjNsxb1hq2RD8
|
||||
# sha256: T37KMj0TnsuvHIzCCmoww2fpfpOBTj7cd4NAqucXcpw
|
||||
acme==0.4.0
|
||||
|
||||
# sha256: 33BQiANlNLGqGpirTfdCEElTF9YbpaKiYpTbK4zeGD8
|
||||
# sha256: lwsV1OdEzzlMeb08C_PRxaCXZ2vOk_1AI2755rZHmPM
|
||||
letsencrypt==0.4.0
|
||||
|
||||
# sha256: D3YDaVFjLsMSEfjI5B5D5tn5FeWUtNHYXCObw3ih2tg
|
||||
# sha256: VTgvsePYGRmI4IOSAnxoYFHd8KciD73bxIuIHtbVFd8
|
||||
letsencrypt-apache==0.4.0
|
||||
|
||||
# sha256: uDndLZwRfHAUMMFJlWkYpCOphjtIsJyQ4wpgE-fS9E8
|
||||
# sha256: j4MIDaoknQNsvM-4rlzG_wB7iNbZN1ITca-r57Gbrbw
|
||||
mock==1.0.1
|
||||
|
||||
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT;
|
||||
# ADD ALL DEPENDENCIES ABOVE
|
||||
|
||||
# sha256: zd_qpRKPaFs00y5hex5Rbu5CVLWzed7pBGL28juxoHM
|
||||
# sha256: 18Gfo85AbZXE46GyTkyePthTNiUeoGTQNcXlSvmRQvM
|
||||
acme==0.4.1
|
||||
|
||||
# sha256: wIuGh8yh1TeOClXW0qLz70bKeM9Ax4bfFNrkKSDjbbo
|
||||
# sha256: 7TeAUt8cZ0IZQuQNuUm8MoH8vPWlKaCrwWAkdCEs_5s
|
||||
letsencrypt==0.4.1
|
||||
|
||||
# sha256: bnpKXJTXy9cFSktJLtvTCTovJJybc__Ivqs6XaXxk9U
|
||||
# sha256: bcvJ6j5UB8sOJ_M88DAsqvmaLxD2UnAP9ys-_J6Bdcc
|
||||
letsencrypt-apache==0.4.1
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/peep.py"
|
||||
@@ -745,6 +756,7 @@ except ImportError:
|
||||
from pip.util import url_to_path # 0.7.0
|
||||
except ImportError:
|
||||
from pip.util import url_to_filename as url_to_path # 0.6.2
|
||||
from pip.exceptions import InstallationError
|
||||
from pip.index import PackageFinder, Link
|
||||
try:
|
||||
from pip.log import logger
|
||||
@@ -763,7 +775,7 @@ except ImportError:
|
||||
|
||||
DownloadProgressBar = DownloadProgressSpinner = NullProgressBar
|
||||
|
||||
__version__ = 3, 0, 0
|
||||
__version__ = 3, 1, 1
|
||||
|
||||
try:
|
||||
from pip.index import FormatControl # noqa
|
||||
@@ -781,6 +793,7 @@ ITS_FINE_ITS_FINE = 0
|
||||
SOMETHING_WENT_WRONG = 1
|
||||
# "Traditional" for command-line errors according to optparse docs:
|
||||
COMMAND_LINE_ERROR = 2
|
||||
UNHANDLED_EXCEPTION = 3
|
||||
|
||||
ARCHIVE_EXTENSIONS = ('.tar.bz2', '.tar.gz', '.tgz', '.tar', '.zip')
|
||||
|
||||
@@ -1543,7 +1556,7 @@ def peep_install(argv):
|
||||
first_every_last(buckets[SatisfiedReq], *printers)
|
||||
|
||||
return ITS_FINE_ITS_FINE
|
||||
except (UnsupportedRequirementError, DownloadError) as exc:
|
||||
except (UnsupportedRequirementError, InstallationError, DownloadError) as exc:
|
||||
out(str(exc))
|
||||
return SOMETHING_WENT_WRONG
|
||||
finally:
|
||||
@@ -1563,16 +1576,23 @@ def peep_port(paths):
|
||||
print('Please specify one or more requirements files so I have '
|
||||
'something to port.\n')
|
||||
return COMMAND_LINE_ERROR
|
||||
|
||||
comes_from = None
|
||||
for req in chain.from_iterable(
|
||||
_parse_requirements(path, package_finder(argv)) for path in paths):
|
||||
req_path, req_line = path_and_line(req)
|
||||
hashes = [hexlify(urlsafe_b64decode((hash + '=').encode('ascii'))).decode('ascii')
|
||||
for hash in hashes_above(*path_and_line(req))]
|
||||
for hash in hashes_above(req_path, req_line)]
|
||||
if req_path != comes_from:
|
||||
print()
|
||||
print('# from %s' % req_path)
|
||||
print()
|
||||
comes_from = req_path
|
||||
|
||||
if not hashes:
|
||||
print(req.req)
|
||||
elif len(hashes) == 1:
|
||||
print('%s --hash=sha256:%s' % (req.req, hashes[0]))
|
||||
else:
|
||||
print('%s' % req.req, end='')
|
||||
print('%s' % (req.link if getattr(req, 'link', None) else req.req), end='')
|
||||
for hash in hashes:
|
||||
print(' \\')
|
||||
print(' --hash=sha256:%s' % hash, end='')
|
||||
@@ -1617,7 +1637,7 @@ if __name__ == '__main__':
|
||||
exit(main())
|
||||
except Exception:
|
||||
exception_handler(*sys.exc_info())
|
||||
exit(SOMETHING_WENT_WRONG)
|
||||
exit(UNHANDLED_EXCEPTION)
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -1630,8 +1650,10 @@ UNLIKELY_EOF
|
||||
# Report error. (Otherwise, be quiet.)
|
||||
echo "Had a problem while downloading and verifying Python packages:"
|
||||
echo "$PEEP_OUT"
|
||||
rm -rf "$VENV_PATH"
|
||||
exit 1
|
||||
fi
|
||||
echo "Installation succeeded."
|
||||
fi
|
||||
echo "Requesting root privileges to run letsencrypt..."
|
||||
echo " " $SUDO "$VENV_BIN/letsencrypt" "$@"
|
||||
@@ -1653,10 +1675,11 @@ else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Checking for new version..."
|
||||
TEMP_DIR=$(TempDir)
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py"
|
||||
if [ "$NO_SELF_UPGRADE" != 1 ]; then
|
||||
echo "Checking for new version..."
|
||||
TEMP_DIR=$(TempDir)
|
||||
# ---------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/fetch.py"
|
||||
"""Do downloading and JSON parsing without additional dependencies. ::
|
||||
|
||||
# Print latest released version of LE to stdout:
|
||||
@@ -1785,25 +1808,36 @@ if __name__ == '__main__':
|
||||
exit(main())
|
||||
|
||||
UNLIKELY_EOF
|
||||
# ---------------------------------------------------------------------------
|
||||
DeterminePythonVersion
|
||||
REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version`
|
||||
if [ "$LE_AUTO_VERSION" != "$REMOTE_VERSION" ]; then
|
||||
echo "Upgrading letsencrypt-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
|
||||
# ---------------------------------------------------------------------------
|
||||
DeterminePythonVersion
|
||||
REMOTE_VERSION=`"$LE_PYTHON" "$TEMP_DIR/fetch.py" --latest-version`
|
||||
if [ "$LE_AUTO_VERSION" != "$REMOTE_VERSION" ]; then
|
||||
echo "Upgrading letsencrypt-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
|
||||
|
||||
# Now we drop into Python so we don't have to install even more
|
||||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
|
||||
# Now we drop into Python so we don't have to install even more
|
||||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
|
||||
|
||||
# Install new copy of letsencrypt-auto. This preserves permissions and
|
||||
# ownership from the old copy.
|
||||
# TODO: Deal with quotes in pathnames.
|
||||
echo "Replacing letsencrypt-auto..."
|
||||
echo " " $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$0"
|
||||
$SUDO cp "$TEMP_DIR/letsencrypt-auto" "$0"
|
||||
# TODO: Clean up temp dir safely, even if it has quotes in its path.
|
||||
rm -rf "$TEMP_DIR"
|
||||
fi # should upgrade
|
||||
"$0" --no-self-upgrade "$@"
|
||||
# Install new copy of letsencrypt-auto.
|
||||
# TODO: Deal with quotes in pathnames.
|
||||
echo "Replacing letsencrypt-auto..."
|
||||
# Clone permissions with cp. chmod and chown don't have a --reference
|
||||
# option on OS X or BSD, and stat -c on Linux is stat -f on OS X and BSD:
|
||||
echo " " $SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
$SUDO cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
echo " " $SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
$SUDO cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
# Using mv rather than cp leaves the old file descriptor pointing to the
|
||||
# original copy so the shell can continue to read it unmolested. mv across
|
||||
# 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.
|
||||
echo " " $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 # Self-upgrading is allowed.
|
||||
|
||||
"$0" --le-auto-phase2 "$@"
|
||||
fi
|
||||
|
||||
@@ -646,22 +646,25 @@ zope.event==4.1.0
|
||||
# sha256: sJyMHUezUxxADgGVaX8UFKYyId5u9HhZik8UYPfZo5I
|
||||
zope.interface==4.1.3
|
||||
|
||||
# sha256: ilvjjTWOS86xchl0WBZ0YOAw_0rmqdnjNsxb1hq2RD8
|
||||
# sha256: T37KMj0TnsuvHIzCCmoww2fpfpOBTj7cd4NAqucXcpw
|
||||
acme==0.4.0
|
||||
|
||||
# sha256: 33BQiANlNLGqGpirTfdCEElTF9YbpaKiYpTbK4zeGD8
|
||||
# sha256: lwsV1OdEzzlMeb08C_PRxaCXZ2vOk_1AI2755rZHmPM
|
||||
letsencrypt==0.4.0
|
||||
|
||||
# sha256: D3YDaVFjLsMSEfjI5B5D5tn5FeWUtNHYXCObw3ih2tg
|
||||
# sha256: VTgvsePYGRmI4IOSAnxoYFHd8KciD73bxIuIHtbVFd8
|
||||
letsencrypt-apache==0.4.0
|
||||
|
||||
# sha256: uDndLZwRfHAUMMFJlWkYpCOphjtIsJyQ4wpgE-fS9E8
|
||||
# sha256: j4MIDaoknQNsvM-4rlzG_wB7iNbZN1ITca-r57Gbrbw
|
||||
mock==1.0.1
|
||||
|
||||
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT;
|
||||
# ADD ALL DEPENDENCIES ABOVE
|
||||
|
||||
# sha256: zd_qpRKPaFs00y5hex5Rbu5CVLWzed7pBGL28juxoHM
|
||||
# sha256: 18Gfo85AbZXE46GyTkyePthTNiUeoGTQNcXlSvmRQvM
|
||||
acme==0.4.1
|
||||
|
||||
# sha256: wIuGh8yh1TeOClXW0qLz70bKeM9Ax4bfFNrkKSDjbbo
|
||||
# sha256: 7TeAUt8cZ0IZQuQNuUm8MoH8vPWlKaCrwWAkdCEs_5s
|
||||
letsencrypt==0.4.1
|
||||
|
||||
# sha256: bnpKXJTXy9cFSktJLtvTCTovJJybc__Ivqs6XaXxk9U
|
||||
# sha256: bcvJ6j5UB8sOJ_M88DAsqvmaLxD2UnAP9ys-_J6Bdcc
|
||||
letsencrypt-apache==0.4.1
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
cat << "UNLIKELY_EOF" > "$TEMP_DIR/peep.py"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
XQAAAAT//////////wBCghGWcdbIc2Jwx9eNx/8BCz2bNPFlhMANgkl2y9DXQ35eeVwpAz1hka/X
|
||||
mbAtebf8wyUrVCYJ295X4aa52T2/hffWukE1K2mV5ZNV2IstEohx5ghX536mksyW2pLB5K6pttTs
|
||||
Zg4DW17p/vWM/VczjT5yhIlR+ZAKcSKGSiMhJXLnvF0UKcQ6RJ2CFdfQhPkEEtjHlWPPlLRc8K9/
|
||||
DyPI1KeAoER9MMl/sZELr7gRJh8vpDV9XtVwQ0RhH59/Xze6s/WvaMf2C08IWysSW/BulLu9YbEs
|
||||
oOiW7OKECzryCNcg4+QISNcoiKUEDGUYbQWMfcB1I0hYjl5HZ332R1ljr9UbdGGdUAF0zby+LvrT
|
||||
///9TmAA
|
||||
@@ -197,18 +197,21 @@ zope.event==4.1.0
|
||||
# sha256: sJyMHUezUxxADgGVaX8UFKYyId5u9HhZik8UYPfZo5I
|
||||
zope.interface==4.1.3
|
||||
|
||||
# sha256: ilvjjTWOS86xchl0WBZ0YOAw_0rmqdnjNsxb1hq2RD8
|
||||
# sha256: T37KMj0TnsuvHIzCCmoww2fpfpOBTj7cd4NAqucXcpw
|
||||
acme==0.4.0
|
||||
|
||||
# sha256: 33BQiANlNLGqGpirTfdCEElTF9YbpaKiYpTbK4zeGD8
|
||||
# sha256: lwsV1OdEzzlMeb08C_PRxaCXZ2vOk_1AI2755rZHmPM
|
||||
letsencrypt==0.4.0
|
||||
|
||||
# sha256: D3YDaVFjLsMSEfjI5B5D5tn5FeWUtNHYXCObw3ih2tg
|
||||
# sha256: VTgvsePYGRmI4IOSAnxoYFHd8KciD73bxIuIHtbVFd8
|
||||
letsencrypt-apache==0.4.0
|
||||
|
||||
# sha256: uDndLZwRfHAUMMFJlWkYpCOphjtIsJyQ4wpgE-fS9E8
|
||||
# sha256: j4MIDaoknQNsvM-4rlzG_wB7iNbZN1ITca-r57Gbrbw
|
||||
mock==1.0.1
|
||||
|
||||
# THE LINES BELOW ARE EDITED BY THE RELEASE SCRIPT;
|
||||
# ADD ALL DEPENDENCIES ABOVE
|
||||
|
||||
# sha256: zd_qpRKPaFs00y5hex5Rbu5CVLWzed7pBGL28juxoHM
|
||||
# sha256: 18Gfo85AbZXE46GyTkyePthTNiUeoGTQNcXlSvmRQvM
|
||||
acme==0.4.1
|
||||
|
||||
# sha256: wIuGh8yh1TeOClXW0qLz70bKeM9Ax4bfFNrkKSDjbbo
|
||||
# sha256: 7TeAUt8cZ0IZQuQNuUm8MoH8vPWlKaCrwWAkdCEs_5s
|
||||
letsencrypt==0.4.1
|
||||
|
||||
# sha256: bnpKXJTXy9cFSktJLtvTCTovJJybc__Ivqs6XaXxk9U
|
||||
# sha256: bcvJ6j5UB8sOJ_M88DAsqvmaLxD2UnAP9ys-_J6Bdcc
|
||||
letsencrypt-apache==0.4.1
|
||||
|
||||
+4
-1
@@ -872,7 +872,10 @@ def _restore_webroot_config(config, renewalparams):
|
||||
setattr(config.namespace, "webroot_map", renewalparams["webroot_map"])
|
||||
elif "webroot_path" in renewalparams:
|
||||
logger.info("Ancient renewal conf file without webroot-map, restoring webroot-path")
|
||||
setattr(config.namespace, "webroot_path", renewalparams["webroot_path"])
|
||||
wp = renewalparams["webroot_path"]
|
||||
if isinstance(wp, str): # prior to 0.1.0, webroot_path was a string
|
||||
wp = [wp]
|
||||
setattr(config.namespace, "webroot_path", wp)
|
||||
|
||||
|
||||
def _reconstitute(config, full_path):
|
||||
|
||||
@@ -20,6 +20,7 @@ from letsencrypt import constants
|
||||
from letsencrypt import crypto_util
|
||||
from letsencrypt import errors
|
||||
from letsencrypt import le_util
|
||||
from letsencrypt import storage
|
||||
|
||||
from letsencrypt.plugins import disco
|
||||
from letsencrypt.plugins import manual
|
||||
@@ -630,8 +631,9 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
||||
print "Logs:"
|
||||
print lf.read()
|
||||
|
||||
def test_renew_verb(self):
|
||||
with open(test_util.vector_path('sample-renewal.conf')) as src:
|
||||
|
||||
def _make_test_renewal_conf(self, testfile):
|
||||
with open(test_util.vector_path(testfile)) as src:
|
||||
# put the correct path for cert.pem, chain.pem etc in the renewal conf
|
||||
renewal_conf = src.read().replace("MAGICDIR", test_util.vector_path())
|
||||
rd = os.path.join(self.config_dir, "renewal")
|
||||
@@ -640,9 +642,26 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
||||
rc = os.path.join(rd, "sample-renewal.conf")
|
||||
with open(rc, "w") as dest:
|
||||
dest.write(renewal_conf)
|
||||
return rc
|
||||
|
||||
def test_renew_verb(self):
|
||||
self._make_test_renewal_conf('sample-renewal.conf')
|
||||
args = ["renew", "--dry-run", "-tvv"]
|
||||
self._test_renewal_common(True, [], args=args, renew=True)
|
||||
|
||||
@mock.patch("letsencrypt.cli._set_by_cli")
|
||||
def test_ancient_webroot_renewal_conf(self, mock_set_by_cli):
|
||||
mock_set_by_cli.return_value = False
|
||||
rc_path = self._make_test_renewal_conf('sample-renewal-ancient.conf')
|
||||
args = mock.MagicMock(account=None, email=None, webroot_path=None)
|
||||
config = configuration.NamespaceConfig(args)
|
||||
lineage = storage.RenewableCert(rc_path,
|
||||
configuration.RenewerConfiguration(config))
|
||||
renewalparams = lineage.configuration["renewalparams"]
|
||||
# pylint: disable=protected-access
|
||||
cli._restore_webroot_config(config, renewalparams)
|
||||
self.assertEqual(config.webroot_path, ["/var/www/"])
|
||||
|
||||
def test_renew_verb_empty_config(self):
|
||||
rd = os.path.join(self.config_dir, 'renewal')
|
||||
if not os.path.exists(rd):
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
cert = MAGICDIR/live/sample-renewal/cert.pem
|
||||
privkey = MAGICDIR/live/sample-renewal/privkey.pem
|
||||
chain = MAGICDIR/live/sample-renewal/chain.pem
|
||||
fullchain = MAGICDIR/live/sample-renewal/fullchain.pem
|
||||
renew_before_expiry = 1 year
|
||||
|
||||
# Options and defaults used in the renewal process
|
||||
[renewalparams]
|
||||
no_self_upgrade = False
|
||||
apache_enmod = a2enmod
|
||||
no_verify_ssl = False
|
||||
ifaces = None
|
||||
apache_dismod = a2dismod
|
||||
register_unsafely_without_email = False
|
||||
apache_handle_modules = True
|
||||
uir = None
|
||||
installer = none
|
||||
nginx_ctl = nginx
|
||||
config_dir = MAGICDIR
|
||||
text_mode = False
|
||||
func = <function obtain_cert at 0x7f093a163c08>
|
||||
staging = True
|
||||
prepare = False
|
||||
work_dir = /var/lib/letsencrypt
|
||||
tos = False
|
||||
init = False
|
||||
http01_port = 80
|
||||
duplicate = False
|
||||
noninteractive_mode = True
|
||||
key_path = None
|
||||
nginx = False
|
||||
nginx_server_root = /etc/nginx
|
||||
fullchain_path = /home/ubuntu/letsencrypt/chain.pem
|
||||
email = None
|
||||
csr = None
|
||||
agree_dev_preview = None
|
||||
redirect = None
|
||||
verb = certonly
|
||||
verbose_count = -3
|
||||
config_file = None
|
||||
renew_by_default = False
|
||||
hsts = False
|
||||
apache_handle_sites = True
|
||||
authenticator = webroot
|
||||
domains = isnot.org,
|
||||
rsa_key_size = 2048
|
||||
apache_challenge_location = /etc/apache2
|
||||
checkpoints = 1
|
||||
manual_test_mode = False
|
||||
apache = False
|
||||
cert_path = /home/ubuntu/letsencrypt/cert.pem
|
||||
webroot_path = /var/www/
|
||||
reinstall = False
|
||||
expand = False
|
||||
strict_permissions = False
|
||||
apache_server_root = /etc/apache2
|
||||
account = None
|
||||
dry_run = False
|
||||
manual_public_ip_logging_ok = False
|
||||
chain_path = /home/ubuntu/letsencrypt/chain.pem
|
||||
break_my_certs = False
|
||||
standalone = True
|
||||
manual = False
|
||||
server = https://acme-staging.api.letsencrypt.org/directory
|
||||
standalone_supported_challenges = "tls-sni-01,http-01"
|
||||
webroot = True
|
||||
os_packages_only = False
|
||||
apache_init_script = None
|
||||
user_agent = None
|
||||
apache_le_vhost_ext = -le-ssl.conf
|
||||
debug = False
|
||||
tls_sni_01_port = 443
|
||||
logs_dir = /var/log/letsencrypt
|
||||
apache_vhost_root = /etc/apache2/sites-available
|
||||
configurator = None
|
||||
+1
-1
@@ -2,7 +2,7 @@ cert = MAGICDIR/live/sample-renewal/cert.pem
|
||||
privkey = MAGICDIR/live/sample-renewal/privkey.pem
|
||||
chain = MAGICDIR/live/sample-renewal/chain.pem
|
||||
fullchain = MAGICDIR/live/sample-renewal/fullchain.pem
|
||||
renew_before_expiry = 1 year
|
||||
renew_before_expiry = 4 years
|
||||
|
||||
# Options and defaults used in the renewal process
|
||||
[renewalparams]
|
||||
|
||||
@@ -39,7 +39,7 @@ install_requires = [
|
||||
'ConfigArgParse>=0.9.3',
|
||||
'configobj',
|
||||
'cryptography>=0.7', # load_pem_x509_certificate
|
||||
'parsedatetime',
|
||||
'parsedatetime<2.0', # parsedatetime 2.0 doesn't work on py26
|
||||
'psutil>=2.1.0', # net_connections introduced in 2.1.0
|
||||
'PyOpenSSL',
|
||||
'pyrfc3339',
|
||||
|
||||
@@ -68,7 +68,7 @@ common renew
|
||||
CheckCertCount 2
|
||||
|
||||
# This will renew because the expiry is less than 10 years from now
|
||||
sed -i "4arenew_before_expiry = 10 years" "$root/conf/renewal/le.wtf.conf"
|
||||
sed -i "4arenew_before_expiry = 4 years" "$root/conf/renewal/le.wtf.conf"
|
||||
common_no_force_renew renew --rsa-key-size 2048
|
||||
CheckCertCount 3
|
||||
|
||||
|
||||
@@ -161,6 +161,23 @@ for module in letsencrypt $subpkgs_modules ; do
|
||||
done
|
||||
deactivate
|
||||
|
||||
# pin peep hashes of the things we just built
|
||||
for pkg in acme letsencrypt letsencrypt-apache ; do
|
||||
echo
|
||||
letsencrypt-auto-source/pieces/peep.py hash dist."$version/$pkg"/*.{whl,gz}
|
||||
echo $pkg==$version
|
||||
done > /tmp/hashes.$$
|
||||
|
||||
if ! wc -l /tmp/hashes.$$ | grep -qE "^\s*12 " ; then
|
||||
echo Unexpected peep hash output
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# perform hideous surgery on requirements.txt...
|
||||
head -n -12 letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt > /tmp/req.$$
|
||||
cat /tmp/hashes.$$ >> /tmp/req.$$
|
||||
cp /tmp/req.$$ letsencrypt-auto-source/pieces/letsencrypt-auto-requirements.txt
|
||||
|
||||
# ensure we have the latest built version of leauto
|
||||
letsencrypt-auto-source/build.py
|
||||
|
||||
|
||||
Reference in New Issue
Block a user