Add timeout to certbot-auto HTTPS fetches. Fix #4473.

This commit is contained in:
Chris J
2017-09-18 09:52:17 -04:00
committed by Erik Rose
parent 331d12ed50
commit 9be4fedeec
2 changed files with 18 additions and 14 deletions
+9 -7
View File
@@ -1144,7 +1144,9 @@ from os.path import dirname, join
import re import re
from subprocess import check_call, CalledProcessError from subprocess import check_call, CalledProcessError
from sys import argv, exit from sys import argv, exit
from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPError from urllib2 import build_opener, HTTPHandler, HTTPSHandler
from urllib2 import HTTPError, URLError
import socket
PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY----- PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq
@@ -1173,15 +1175,15 @@ class HttpsGetter(object):
if isinstance(handler, HTTPHandler): if isinstance(handler, HTTPHandler):
self._opener.handlers.remove(handler) self._opener.handlers.remove(handler)
def get(self, url): def get(self, url, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
"""Return the document contents pointed to by an HTTPS URL. """Return the document contents pointed to by an HTTPS URL.
If something goes wrong (404, timeout, etc.), raise ExpectedError. If something goes wrong (404, timeout, etc.), raise ExpectedError.
""" """
try: try:
return self._opener.open(url).read() return self._opener.open(url, timeout = timeout).read()
except (HTTPError, IOError) as exc: except (HTTPError, URLError, IOError) as exc:
raise ExpectedError("Couldn't download %s." % url, exc) raise ExpectedError("Couldn't download %s." % url, exc)
@@ -1195,7 +1197,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/certbot/json'))) 'https://pypi.python.org/pypi/certbot/json'), timeout = 10))
# 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
@@ -1216,8 +1218,8 @@ def verified_new_le_auto(get, tag, temp_dir):
'LE_AUTO_DIR_TEMPLATE', 'LE_AUTO_DIR_TEMPLATE',
'https://raw.githubusercontent.com/certbot/certbot/%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', timeout = 10), 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', timeout = 10), temp_dir, 'letsencrypt-auto.sig')
write(PUBLIC_KEY, temp_dir, 'public_key.pem') write(PUBLIC_KEY, temp_dir, 'public_key.pem')
try: try:
with open(devnull, 'w') as dev_null: with open(devnull, 'w') as dev_null:
+9 -7
View File
@@ -20,7 +20,9 @@ from os.path import dirname, join
import re import re
from subprocess import check_call, CalledProcessError from subprocess import check_call, CalledProcessError
from sys import argv, exit from sys import argv, exit
from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPError from urllib2 import build_opener, HTTPHandler, HTTPSHandler
from urllib2 import HTTPError, URLError
import socket
PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY----- PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq
@@ -49,15 +51,15 @@ class HttpsGetter(object):
if isinstance(handler, HTTPHandler): if isinstance(handler, HTTPHandler):
self._opener.handlers.remove(handler) self._opener.handlers.remove(handler)
def get(self, url): def get(self, url, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
"""Return the document contents pointed to by an HTTPS URL. """Return the document contents pointed to by an HTTPS URL.
If something goes wrong (404, timeout, etc.), raise ExpectedError. If something goes wrong (404, timeout, etc.), raise ExpectedError.
""" """
try: try:
return self._opener.open(url).read() return self._opener.open(url, timeout = timeout).read()
except (HTTPError, IOError) as exc: except (HTTPError, URLError, IOError) as exc:
raise ExpectedError("Couldn't download %s." % url, exc) raise ExpectedError("Couldn't download %s." % url, exc)
@@ -71,7 +73,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/certbot/json'))) 'https://pypi.python.org/pypi/certbot/json'), timeout = 10))
# 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
@@ -92,8 +94,8 @@ def verified_new_le_auto(get, tag, temp_dir):
'LE_AUTO_DIR_TEMPLATE', 'LE_AUTO_DIR_TEMPLATE',
'https://raw.githubusercontent.com/certbot/certbot/%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', timeout = 10), 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', timeout = 10), temp_dir, 'letsencrypt-auto.sig')
write(PUBLIC_KEY, temp_dir, 'public_key.pem') write(PUBLIC_KEY, temp_dir, 'public_key.pem')
try: try:
with open(devnull, 'w') as dev_null: with open(devnull, 'w') as dev_null: