From 9be4fedeecf2489f7c707030bb6ad944e68d52d5 Mon Sep 17 00:00:00 2001 From: Chris J Date: Sat, 8 Jul 2017 02:57:42 -0400 Subject: Add timeout to certbot-auto HTTPS fetches. Fix #4473. --- letsencrypt-auto-source/letsencrypt-auto | 16 +++++++++------- letsencrypt-auto-source/pieces/fetch.py | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 276d68c22..9aa4f50fb 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -1144,7 +1144,9 @@ from os.path import dirname, join import re from subprocess import check_call, CalledProcessError 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----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq @@ -1173,15 +1175,15 @@ class HttpsGetter(object): if isinstance(handler, HTTPHandler): 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. If something goes wrong (404, timeout, etc.), raise ExpectedError. """ try: - return self._opener.open(url).read() - except (HTTPError, IOError) as exc: + return self._opener.open(url, timeout = timeout).read() + except (HTTPError, URLError, IOError) as 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.""" metadata = loads(get( 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 # release release, contrary to https://wiki.python.org/moin/PyPIJSON. # 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', 'https://raw.githubusercontent.com/certbot/certbot/%s/' 'letsencrypt-auto-source/') % tag - 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', timeout = 10), temp_dir, 'letsencrypt-auto') + write(get(le_auto_dir + 'letsencrypt-auto.sig', timeout = 10), temp_dir, 'letsencrypt-auto.sig') write(PUBLIC_KEY, temp_dir, 'public_key.pem') try: with open(devnull, 'w') as dev_null: diff --git a/letsencrypt-auto-source/pieces/fetch.py b/letsencrypt-auto-source/pieces/fetch.py index e7ebb9e0a..e296994a6 100644 --- a/letsencrypt-auto-source/pieces/fetch.py +++ b/letsencrypt-auto-source/pieces/fetch.py @@ -20,7 +20,9 @@ from os.path import dirname, join import re from subprocess import check_call, CalledProcessError 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----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq @@ -49,15 +51,15 @@ class HttpsGetter(object): if isinstance(handler, HTTPHandler): 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. If something goes wrong (404, timeout, etc.), raise ExpectedError. """ try: - return self._opener.open(url).read() - except (HTTPError, IOError) as exc: + return self._opener.open(url, timeout = timeout).read() + except (HTTPError, URLError, IOError) as 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.""" metadata = loads(get( 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 # release release, contrary to https://wiki.python.org/moin/PyPIJSON. # 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', 'https://raw.githubusercontent.com/certbot/certbot/%s/' 'letsencrypt-auto-source/') % tag - 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', timeout = 10), temp_dir, 'letsencrypt-auto') + write(get(le_auto_dir + 'letsencrypt-auto.sig', timeout = 10), temp_dir, 'letsencrypt-auto.sig') write(PUBLIC_KEY, temp_dir, 'public_key.pem') try: with open(devnull, 'w') as dev_null: -- cgit v1.2.3