diff --git a/autospec/pkg_integrity.py b/autospec/pkg_integrity.py index a874d42..ed308ea 100644 --- a/autospec/pkg_integrity.py +++ b/autospec/pkg_integrity.py @@ -2,7 +2,6 @@ import argparse import hashlib -import json import os import re import shutil @@ -39,7 +38,6 @@ pubkey --gnupghome /opt/pki/gpghome """.format(fn=__file__) SEPT = "-------------------------------------------------------------------------------" -PYPIORG_API = "https://pypi.python.org/pypi/{}/json" KEYID_TRY = "" KEYID = "" IMPORTED = "" @@ -50,13 +48,6 @@ ENV = os.environ INPUT_GETTER_TIMEOUT = 60 CHUNK_SIZE = 2056 -PYPI_DOMAINS = [ - 'files.pythonhosted.org', - 'pypi.debian.net', - 'pypi.python.org', - 'pypi.io', -] - KEY_CACHE_DIR = os.path.expanduser('~/.cache/clr-pkg-key-cache') @@ -252,8 +243,6 @@ def get_signature_file(package_url, package_path): netloc = urlparse(package_url).netloc if 'samba.org' in netloc: sign_urls.append(package_url + '.asc') - elif any(loc in netloc for loc in PYPI_DOMAINS): - sign_urls.append(package_url + '.asc') elif 'mirrors.kernel.org' in netloc: sign_urls.append(package_url + '.sig') else: @@ -443,69 +432,6 @@ class QtIoVerifier(ShaSumVerifier): return self.verify_sum(shasum) -# PyPi Verifier -class PyPiVerifier(ShaSumVerifier): - """Verify SHA256 digest for pypi.""" - - def __init__(self, **kwargs): - """Initialize with sha256.""" - kwargs.update({'shalen': 256}) - ShaSumVerifier.__init__(self, **kwargs) - - def parse_name(self): - """Get pypi package name and release number.""" - pkg_name = os.path.basename(self.package_path) - name, _ = re.split(r'-\d+\.', pkg_name, maxsplit=1) - release_no = pkg_name.replace(name + '-', '') - extensions = "({})".format("|".join([r'\.tar\.gz$', r'\.zip$', r'\.tgz$', r'\.tar\.bz2$'])) - ext = re.search(extensions, release_no) - if ext is not None: - release_no = release_no.replace(ext.group(), '') - return name, release_no - - @staticmethod - def get_info(package_name): - """Get json dump of pypi package.""" - url = PYPIORG_API.format(package_name) - data = download.do_curl(url) - if data: - return json.loads(data.getvalue().decode('utf-8')) - else: - return {} - - @staticmethod - def get_source_release(package_fullname, releases): - """Lookup release for package name.""" - for release in releases: - if release.get('filename', 'not_found') == package_fullname: - return release - return {} - - def verify(self): - """Verify pypi file with SHA256.""" - global EMAIL - util.print_info("Searching for package information in pypi") - name, release = self.parse_name() - info = PyPiVerifier.get_info(name) - releases_info = info.get('releases', None) - if releases_info is None: - self.print_result(False, err_msg=f"Error in package info from {PYPIORG_API.format(name)}") - return None - release_info = releases_info.get(release, None) - if release_info is None: - self.print_result(False, - err_msg='Information for package {} with release {} not found'.format(name, release)) - return None - release_info = self.get_source_release(os.path.basename(self.package_path), release_info) - package_info = info.get('info', None) - if package_info is not None: - EMAIL = package_info.get('author_email', '') - sha256 = '' - if digests := release_info.get('digests', ''): - sha256 = digests.get('sha256', '') - return self.verify_sum(sha256) - - # GPG Verification class GPGVerifier(Verifier): """Verify GPG signature.""" @@ -794,16 +720,13 @@ def from_disk(url, package_path, package_check, config, interactive=True): def attempt_verification_per_domain(package_path, url): """Use url domain name to set verification type.""" netloc = urlparse(url).netloc - if any(loc in netloc for loc in PYPI_DOMAINS): - domain = 'pypi' - elif 'download.gnome.org' in netloc: + if 'download.gnome.org' in netloc: domain = 'gnome.org' elif 'download.qt.io' in netloc: domain = 'qt.io' else: domain = 'unknown' verifier = { - 'pypi': PyPiVerifier, 'gnome.org': GnomeOrgVerifier, 'qt.io': QtIoVerifier, }.get(domain, None) diff --git a/tests/test_pkg_integrity.py b/tests/test_pkg_integrity.py index 0dca099..0cef927 100644 --- a/tests/test_pkg_integrity.py +++ b/tests/test_pkg_integrity.py @@ -15,12 +15,10 @@ TESTDIR = os.path.join(os.getcwd(), "tests/testfiles/pkg_integrity") TESTKEYDIR = os.path.join(TESTDIR, "testkeys") PACKAGE_URL = "http://pkgconfig.freedesktop.org/releases/pkg-config-0.29.1.tar.gz" -XATTR_PKT_URL = "http://pypi.debian.net/xattr/xattr-0.9.1.tar.gz" NO_SIGN_PKT_URL = "http://www.ferzkopp.net/Software/SDL_gfx-2.0/SDL_gfx-2.0.25.tar.gz" NOSIGN_PKT_URL_BAD = "http://gnu.mirrors.pair.com/savannah/savannah/quagga/bad_quagga-1.1.0.tar.gz" NOSIGN_PKT_URL = "http://download.savannah.gnu.org/releases/quagga/quagga-1.1.0.tar.gz" NOSIGN_SIGN_URL = "http://download.savannah.gnu.org/releases/quagga/quagga-1.1.0.tar.gz.asc" -PYPI_SHA256_PKG = "http://pypi.debian.net/tappy/tappy-0.9.2.tar.gz" GNOME_SHA256_PKG = "https://download.gnome.org/sources/pygobject/3.24/pygobject-3.24.0.tar.xz" QT_SHA256_PKG = "https://download.qt.io/official_releases/qt/5.12/5.12.4/submodules/qtspeech-everywhere-src-5.12.4.tar.xz" KEYID = "EC2392F2EDE74488680DA3CF5F2B4756ED873D23" @@ -73,29 +71,6 @@ class TestCheckFn(unittest.TestCase): @patch('download.do_curl', mock_download_do_curl) class TestDomainBasedVerifiers(unittest.TestCase): - def _mock_pypi_get_info(pkg): - info = ''' - { - "info": { - "author_email": "user@example.com", - "name": "tappy" - }, - "releases": { - "0.9.0": [], - "0.9.2": [ - { - "digests": { - "md5": "82e7f161746987b4da64c3347a2a2959", - "sha256": "c0a53bd9309c5bd5296bf1747b6127551f14f617dfed218c2f3fa2714c5f695f" - }, - "filename": "tappy-0.9.2.tar.gz" - } - ] - } - } - ''' - return json.loads(info) - def run_test_for_domain(self, Verifier, url): with tempfile.TemporaryDirectory() as tmpd: filen = os.path.basename(url) @@ -106,11 +81,6 @@ class TestDomainBasedVerifiers(unittest.TestCase): return verifier.verify() return None - @patch('pkg_integrity.PyPiVerifier.get_info', _mock_pypi_get_info) - def test_pypi(self): - result = self.run_test_for_domain(pkg_integrity.PyPiVerifier, PYPI_SHA256_PKG) - self.assertTrue(result) - def _mock_fetch_shasum(url): return ( "100395496483fcea7ba03fc1655c7a770f7f2e12e93be8bda2e31fec42debde0 pygobject-3.24.0.news\n" @@ -361,10 +331,8 @@ class TestUtils(unittest.TestCase): def _mock_download_file(url, dst=None): # make return codes match by url to ensure we are using the expected signature type if url in ("http://ftp.gnu.org/pub/gnu/gperf/gperf-3.0.4.tar.gz.sig", - "http://download.savannah.gnu.org/releases/quilt/quilt-0.65.tar.gz.asc", - "http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2.sign", - "http://pypi.debian.net/cmd2/cmd2-0.6.9.tar.gz.asc", - "https://pypi.python.org/packages/c6/fe/97319581905de40f1be7015a0ea1bd336a756f6249914b148a17eefa75dc/Cython-0.24.1.tar.gz.asc"): + "http://download.savannah.gnu.org/releases/quilt/quilt-0.65.tar.gz.asc", + "http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2.sign"): return os.path.join(dst, os.path.basename(url)) return None @@ -373,14 +341,10 @@ class TestUtils(unittest.TestCase): url_from_gnu = "http://ftp.gnu.org/pub/gnu/gperf/gperf-3.0.4.tar.gz" url_from_gnu1 = "http://download.savannah.gnu.org/releases/quilt/quilt-0.65.tar.gz" url_from_gnu2 = "http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2" - url_from_pypi = "http://pypi.debian.net/cmd2/cmd2-0.6.9.tar.gz" - url_from_pypi1 = "https://pypi.python.org/packages/c6/fe/97319581905de40f1be7015a0ea1bd336a756f6249914b148a17eefa75dc/Cython-0.24.1.tar.gz" self.assertEqual(pkg_integrity.get_signature_file(url_from_gnu, '.')[-4:], '.sig') - self.assertEqual(pkg_integrity.get_signature_file(url_from_pypi, '.')[-4:], '.asc') self.assertEqual(pkg_integrity.get_signature_file(url_from_gnu1, '.')[-4:], '.asc') self.assertEqual(pkg_integrity.get_signature_file(url_from_gnu2, '.')[-5:], '.sign') - self.assertEqual(pkg_integrity.get_signature_file(url_from_pypi1, '.')[-4:], '.asc') def test_parse_gpg_packets_for_email(self): """Test parse_gpg_packets() to retrieve email info."""