Merge remote-tracking branch 'origin/master' into renew-exit

This commit is contained in:
Peter Eckersley
2016-02-23 13:55:53 -08:00
22 changed files with 1963 additions and 31 deletions
+1
View File
@@ -26,3 +26,4 @@ letsencrypt.log
# letstest # letstest
tests/letstest/letest-*/ tests/letstest/letest-*/
tests/letstest/*.pem tests/letstest/*.pem
tests/letstest/venv/
+4
View File
@@ -0,0 +1,4 @@
[pep8]
# E265 block comment should start with '# '
# E501 line too long (X > 79 characters)
ignore = E265,E501
+1 -1
View File
@@ -42,7 +42,7 @@ csr = OpenSSL.crypto.load_certificate_request(
OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string( OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string(
'acme', os.path.join('testdata', 'csr.der'))) 'acme', os.path.join('testdata', 'csr.der')))
try: try:
acme.request_issuance(csr, (authzr,)) acme.request_issuance(jose.util.ComparableX509(csr), (authzr,))
except messages.Error as error: except messages.Error as error:
print ("This script is doomed to fail as no authorization " print ("This script is doomed to fail as no authorization "
"challenges are ever solved. Error from server: {0}".format(error)) "challenges are ever solved. Error from server: {0}".format(error))
@@ -895,9 +895,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
for addr in vhost.addrs: for addr in vhost.addrs:
# In Apache 2.2, when a NameVirtualHost directive is not # In Apache 2.2, when a NameVirtualHost directive is not
# set, "*" and "_default_" will conflict when sharing a port # set, "*" and "_default_" will conflict when sharing a port
addrs = set((addr,))
if addr.get_addr() in ("*", "_default_"): if addr.get_addr() in ("*", "_default_"):
addrs = [obj.Addr((a, addr.get_port(),)) addrs.update(obj.Addr((a, addr.get_port(),))
for a in ("*", "_default_")] for a in ("*", "_default_"))
for test_vh in self.vhosts: for test_vh in self.vhosts:
if (vhost.filep != test_vh.filep and if (vhost.filep != test_vh.filep and
@@ -907,6 +908,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
self.add_name_vhost(addr) self.add_name_vhost(addr)
logger.info("Enabling NameVirtualHosts on %s", addr) logger.info("Enabling NameVirtualHosts on %s", addr)
need_to_save = True need_to_save = True
break
if need_to_save: if need_to_save:
self.save() self.save()
@@ -1073,7 +1075,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# even with save() and load() # even with save() and load()
if not self._is_rewrite_engine_on(general_vh): if not self._is_rewrite_engine_on(general_vh):
self.parser.add_dir(general_vh.path, "RewriteEngine", "on") self.parser.add_dir(general_vh.path, "RewriteEngine", "on")
names = ssl_vhost.get_names()
for idx, name in enumerate(names):
args = ["%{SERVER_NAME}", "={0}".format(name), "[OR]"]
if idx == len(names) - 1:
args.pop()
self.parser.add_dir(general_vh.path, "RewriteCond", args)
if self.get_version() >= (2, 3, 9): if self.get_version() >= (2, 3, 9):
self.parser.add_dir(general_vh.path, "RewriteRule", self.parser.add_dir(general_vh.path, "RewriteRule",
constants.REWRITE_HTTPS_ARGS_WITH_END) constants.REWRITE_HTTPS_ARGS_WITH_END)
@@ -1243,6 +1250,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
for http_vh in candidate_http_vhs: for http_vh in candidate_http_vhs:
if http_vh.same_server(ssl_vhost): if http_vh.same_server(ssl_vhost):
return http_vh return http_vh
# Third filter - if none with same names, return generic
for http_vh in candidate_http_vhs:
if http_vh.same_server(ssl_vhost, generic=True):
return http_vh
return None return None
+12 -6
View File
@@ -189,22 +189,28 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods
return True return True
return False return False
def same_server(self, vhost): def same_server(self, vhost, generic=False):
"""Determines if the vhost is the same 'server'. """Determines if the vhost is the same 'server'.
Used in redirection - indicates whether or not the two virtual hosts Used in redirection - indicates whether or not the two virtual hosts
serve on the exact same IP combinations, but different ports. serve on the exact same IP combinations, but different ports.
The generic flag indicates that that we're trying to match to a
default or generic vhost
.. todo:: Handle _default_ .. todo:: Handle _default_
""" """
if vhost.get_names() != self.get_names(): if not generic:
return False if vhost.get_names() != self.get_names():
return False
# If equal and set is not empty... assume same server # If equal and set is not empty... assume same server
if self.name is not None or self.aliases: if self.name is not None or self.aliases:
return True return True
# If we're looking for a generic vhost, don't return one with a ServerName
elif self.name:
return False
# Both sets of names are empty. # Both sets of names are empty.
@@ -477,7 +477,7 @@ class ApacheParser(object):
# Note: This works for augeas globs, ie. *.conf # Note: This works for augeas globs, ie. *.conf
if use_new: if use_new:
inc_test = self.aug.match( inc_test = self.aug.match(
"/augeas/load/Httpd/incl [. ='%s']" % filepath) "/augeas/load/Httpd['%s' =~ glob(incl)]" % filepath)
if not inc_test: if not inc_test:
# Load up files # Load up files
# This doesn't seem to work on TravisCI # This doesn't seem to work on TravisCI
@@ -746,9 +746,9 @@ class TwoVhost80Test(util.ApacheTest):
self.config.parser.modules.add("rewrite_module") self.config.parser.modules.add("rewrite_module")
mock_exe.return_value = True mock_exe.return_value = True
ssl_vh = obj.VirtualHost( ssl_vh = obj.VirtualHost(
"fp", "ap", set([obj.Addr(("*", "443")), "fp", "ap", set([obj.Addr(("*", "443"))]),
obj.Addr(("satoshi.com",))]),
True, False) True, False)
ssl_vh.name = "satoshi.com"
self.config.vhosts.append(ssl_vh) self.config.vhosts.append(ssl_vh)
self.assertRaises( self.assertRaises(
errors.PluginError, errors.PluginError,
@@ -0,0 +1,5 @@
# Depends: dav_svn
<IfModule !mod_dav_svn.c>
Include mods-enabled/dav_svn.load
</IfModule>
LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so
@@ -0,0 +1,3 @@
<IfModule !mod_dav.c>
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
</IfModule>
@@ -0,0 +1,56 @@
# dav_svn.conf - Example Subversion/Apache configuration
#
# For details and further options see the Apache user manual and
# the Subversion book.
#
# NOTE: for a setup with multiple vhosts, you will want to do this
# configuration in /etc/apache2/sites-available/*, not here.
# <Location URL> ... </Location>
# URL controls how the repository appears to the outside world.
# In this example clients access the repository as http://hostname/svn/
# Note, a literal /svn should NOT exist in your document root.
#<Location /svn>
# Uncomment this to enable the repository
#DAV svn
# Set this to the path to your repository
#SVNPath /var/lib/svn
# Alternatively, use SVNParentPath if you have multiple repositories under
# under a single directory (/var/lib/svn/repo1, /var/lib/svn/repo2, ...).
# You need either SVNPath and SVNParentPath, but not both.
#SVNParentPath /var/lib/svn
# Access control is done at 3 levels: (1) Apache authentication, via
# any of several methods. A "Basic Auth" section is commented out
# below. (2) Apache <Limit> and <LimitExcept>, also commented out
# below. (3) mod_authz_svn is a svn-specific authorization module
# which offers fine-grained read/write access control for paths
# within a repository. (The first two layers are coarse-grained; you
# can only enable/disable access to an entire repository.) Note that
# mod_authz_svn is noticeably slower than the other two layers, so if
# you don't need the fine-grained control, don't configure it.
# Basic Authentication is repository-wide. It is not secure unless
# you are using https. See the 'htpasswd' command to create and
# manage the password file - and the documentation for the
# 'auth_basic' and 'authn_file' modules, which you will need for this
# (enable them with 'a2enmod').
#AuthType Basic
#AuthName "Subversion Repository"
#AuthUserFile /etc/apache2/dav_svn.passwd
# To enable authorization via mod_authz_svn (enable that module separately):
#<IfModule mod_authz_svn.c>
#AuthzSVNAccessFile /etc/apache2/dav_svn.authz
#</IfModule>
# The following three lines allow anonymous read, but make
# committers authenticate themselves. It requires the 'authz_user'
# module (enable it with 'a2enmod').
#<LimitExcept GET PROPFIND OPTIONS REPORT>
#Require valid-user
#</LimitExcept>
#</Location>
@@ -0,0 +1,7 @@
# Depends: dav
<IfModule !mod_dav_svn.c>
<IfModule !mod_dav.c>
Include mods-enabled/dav.load
</IfModule>
LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so
</IfModule>
@@ -0,0 +1 @@
../mods-available/authz_svn.load
@@ -0,0 +1 @@
../mods-available/dav.load
@@ -0,0 +1 @@
../mods-available/dav_svn.conf
@@ -0,0 +1 @@
../mods-available/dav_svn.load
@@ -62,7 +62,7 @@ class ApacheTlsSni01(common.TLSSNI01):
return [] return []
# Save any changes to the configuration as a precaution # Save any changes to the configuration as a precaution
# About to make temporary changes to the config # About to make temporary changes to the config
self.configurator.save() self.configurator.save("Changes before challenge setup", True)
# Prepare the server for HTTPS # Prepare the server for HTTPS
self.configurator.prepare_server_https( self.configurator.prepare_server_https(
-1
View File
@@ -1 +0,0 @@
letsencrypt-auto-source/letsencrypt-auto
+1809
View File
File diff suppressed because it is too large Load Diff
+16 -7
View File
@@ -755,6 +755,7 @@ except ImportError:
from pip.util import url_to_path # 0.7.0 from pip.util import url_to_path # 0.7.0
except ImportError: except ImportError:
from pip.util import url_to_filename as url_to_path # 0.6.2 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 from pip.index import PackageFinder, Link
try: try:
from pip.log import logger from pip.log import logger
@@ -773,7 +774,7 @@ except ImportError:
DownloadProgressBar = DownloadProgressSpinner = NullProgressBar DownloadProgressBar = DownloadProgressSpinner = NullProgressBar
__version__ = 3, 0, 0 __version__ = 3, 1, 1
try: try:
from pip.index import FormatControl # noqa from pip.index import FormatControl # noqa
@@ -791,6 +792,7 @@ ITS_FINE_ITS_FINE = 0
SOMETHING_WENT_WRONG = 1 SOMETHING_WENT_WRONG = 1
# "Traditional" for command-line errors according to optparse docs: # "Traditional" for command-line errors according to optparse docs:
COMMAND_LINE_ERROR = 2 COMMAND_LINE_ERROR = 2
UNHANDLED_EXCEPTION = 3
ARCHIVE_EXTENSIONS = ('.tar.bz2', '.tar.gz', '.tgz', '.tar', '.zip') ARCHIVE_EXTENSIONS = ('.tar.bz2', '.tar.gz', '.tgz', '.tar', '.zip')
@@ -1553,7 +1555,7 @@ def peep_install(argv):
first_every_last(buckets[SatisfiedReq], *printers) first_every_last(buckets[SatisfiedReq], *printers)
return ITS_FINE_ITS_FINE return ITS_FINE_ITS_FINE
except (UnsupportedRequirementError, DownloadError) as exc: except (UnsupportedRequirementError, InstallationError, DownloadError) as exc:
out(str(exc)) out(str(exc))
return SOMETHING_WENT_WRONG return SOMETHING_WENT_WRONG
finally: finally:
@@ -1573,16 +1575,23 @@ def peep_port(paths):
print('Please specify one or more requirements files so I have ' print('Please specify one or more requirements files so I have '
'something to port.\n') 'something to port.\n')
return COMMAND_LINE_ERROR return COMMAND_LINE_ERROR
comes_from = None
for req in chain.from_iterable( for req in chain.from_iterable(
_parse_requirements(path, package_finder(argv)) for path in paths): _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') 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: if not hashes:
print(req.req) print(req.req)
elif len(hashes) == 1:
print('%s --hash=sha256:%s' % (req.req, hashes[0]))
else: else:
print('%s' % req.req, end='') print('%s' % (req.link if getattr(req, 'link', None) else req.req), end='')
for hash in hashes: for hash in hashes:
print(' \\') print(' \\')
print(' --hash=sha256:%s' % hash, end='') print(' --hash=sha256:%s' % hash, end='')
@@ -1627,7 +1636,7 @@ if __name__ == '__main__':
exit(main()) exit(main())
except Exception: except Exception:
exception_handler(*sys.exc_info()) exception_handler(*sys.exc_info())
exit(SOMETHING_WENT_WRONG) exit(UNHANDLED_EXCEPTION)
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
+16 -7
View File
@@ -86,6 +86,7 @@ except ImportError:
from pip.util import url_to_path # 0.7.0 from pip.util import url_to_path # 0.7.0
except ImportError: except ImportError:
from pip.util import url_to_filename as url_to_path # 0.6.2 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 from pip.index import PackageFinder, Link
try: try:
from pip.log import logger from pip.log import logger
@@ -104,7 +105,7 @@ except ImportError:
DownloadProgressBar = DownloadProgressSpinner = NullProgressBar DownloadProgressBar = DownloadProgressSpinner = NullProgressBar
__version__ = 3, 0, 0 __version__ = 3, 1, 1
try: try:
from pip.index import FormatControl # noqa from pip.index import FormatControl # noqa
@@ -122,6 +123,7 @@ ITS_FINE_ITS_FINE = 0
SOMETHING_WENT_WRONG = 1 SOMETHING_WENT_WRONG = 1
# "Traditional" for command-line errors according to optparse docs: # "Traditional" for command-line errors according to optparse docs:
COMMAND_LINE_ERROR = 2 COMMAND_LINE_ERROR = 2
UNHANDLED_EXCEPTION = 3
ARCHIVE_EXTENSIONS = ('.tar.bz2', '.tar.gz', '.tgz', '.tar', '.zip') ARCHIVE_EXTENSIONS = ('.tar.bz2', '.tar.gz', '.tgz', '.tar', '.zip')
@@ -884,7 +886,7 @@ def peep_install(argv):
first_every_last(buckets[SatisfiedReq], *printers) first_every_last(buckets[SatisfiedReq], *printers)
return ITS_FINE_ITS_FINE return ITS_FINE_ITS_FINE
except (UnsupportedRequirementError, DownloadError) as exc: except (UnsupportedRequirementError, InstallationError, DownloadError) as exc:
out(str(exc)) out(str(exc))
return SOMETHING_WENT_WRONG return SOMETHING_WENT_WRONG
finally: finally:
@@ -904,16 +906,23 @@ def peep_port(paths):
print('Please specify one or more requirements files so I have ' print('Please specify one or more requirements files so I have '
'something to port.\n') 'something to port.\n')
return COMMAND_LINE_ERROR return COMMAND_LINE_ERROR
comes_from = None
for req in chain.from_iterable( for req in chain.from_iterable(
_parse_requirements(path, package_finder(argv)) for path in paths): _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') 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: if not hashes:
print(req.req) print(req.req)
elif len(hashes) == 1:
print('%s --hash=sha256:%s' % (req.req, hashes[0]))
else: else:
print('%s' % req.req, end='') print('%s' % (req.link if getattr(req, 'link', None) else req.req), end='')
for hash in hashes: for hash in hashes:
print(' \\') print(' \\')
print(' --hash=sha256:%s' % hash, end='') print(' --hash=sha256:%s' % hash, end='')
@@ -958,4 +967,4 @@ if __name__ == '__main__':
exit(main()) exit(main())
except Exception: except Exception:
exception_handler(*sys.exc_info()) exception_handler(*sys.exc_info())
exit(SOMETHING_WENT_WRONG) exit(UNHANDLED_EXCEPTION)
+1
View File
@@ -118,6 +118,7 @@ def make_csr(key_str, domains):
value=", ".join("DNS:%s" % d for d in domains) value=", ".join("DNS:%s" % d for d in domains)
), ),
]) ])
req.set_version(2)
req.set_pubkey(pkey) req.set_pubkey(pkey)
req.sign(pkey, "sha256") req.sign(pkey, "sha256")
return tuple(OpenSSL.crypto.dump_certificate_request(method, req) return tuple(OpenSSL.crypto.dump_certificate_request(method, req)
+6 -1
View File
@@ -1,7 +1,12 @@
#!/bin/sh #!/bin/sh
set -e # Fail fast
# PEP8 is not ignored in ACME
pep8 --config=acme/.pep8 acme
pep8 \ pep8 \
setup.py \ setup.py \
acme \
letsencrypt \ letsencrypt \
letsencrypt-apache \ letsencrypt-apache \
letsencrypt-nginx \ letsencrypt-nginx \
+4 -1
View File
@@ -171,7 +171,10 @@ while ! openssl dgst -sha256 -verify $RELEASE_OPENSSL_PUBKEY -signature \
read -p "Please correctly sign letsencrypt-auto with offline-signrequest.sh" read -p "Please correctly sign letsencrypt-auto with offline-signrequest.sh"
done done
git add letsencrypt-auto-source # copy leauto to the root, overwriting the previous release version
cp -p letsencrypt-auto-source/letsencrypt-auto letsencrypt-auto
git add letsencrypt-auto letsencrypt-auto-source
git diff --cached git diff --cached
git commit --gpg-sign="$RELEASE_GPG_KEY" -m "Release $version" git commit --gpg-sign="$RELEASE_GPG_KEY" -m "Release $version"
git tag --local-user "$RELEASE_GPG_KEY" --sign --message "Release $version" "$tag" git tag --local-user "$RELEASE_GPG_KEY" --sign --message "Release $version" "$tag"