Exemple #1
0
def sign_multi(file_path, endpoint, guid):
    """Sign the internal extensions from a multi-package XPI (if any)."""
    log.info("Signing multi-package file {0}".format(file_path))
    # Extract the multi-package to a temp folder.
    folder = tempfile.mkdtemp()
    try:
        extract_xpi(file_path, folder)
        xpis = glob.glob(os.path.join(folder, u"*.xpi"))
        cert_serial_nums = []  # The certificate serial numbers for the XPIs.
        for xpi in xpis:
            xpi_info = parse_xpi(xpi, check=False)
            if xpi_info["type"] == amo.ADDON_EXTENSION:
                # Sign the internal extensions in place.
                cert_serial_nums.append(call_signing(xpi, endpoint, guid))
        # Repackage (re-zip) the multi-package.
        # We only want the (unique) temporary file name.
        with tempfile.NamedTemporaryFile() as temp_file:
            temp_filename = temp_file.name
        shutil.make_archive(temp_filename, format="zip", root_dir=folder)
        # Now overwrite the current multi-package xpi with the repackaged one.
        # Note that shutil.make_archive automatically added a '.zip' to the end
        # of the base_name provided as first argument.
        shutil.move(u"{0}.zip".format(temp_filename), file_path)
        return u"\n".join([unicode(num) for num in cert_serial_nums])
    finally:
        amo.utils.rm_local_tmp_dir(folder)
Exemple #2
0
def sign_multi(file_path, endpoint, guid):
    """Sign the internal extensions from a multi-package XPI (if any)."""
    log.info('Signing multi-package file {0}'.format(file_path))
    # Extract the multi-package to a temp folder.
    folder = tempfile.mkdtemp()
    try:
        extract_xpi(file_path, folder)
        xpis = glob.glob(os.path.join(folder, u'*.xpi'))
        cert_serial_nums = []  # The certificate serial numbers for the XPIs.
        for xpi in xpis:
            xpi_info = parse_xpi(xpi, check=False)
            if xpi_info['type'] == amo.ADDON_EXTENSION:
                # Sign the internal extensions in place.
                cert_serial_nums.append(call_signing(xpi, endpoint, guid))
        # Repackage (re-zip) the multi-package.
        # We only want the (unique) temporary file name.
        with tempfile.NamedTemporaryFile() as temp_file:
            temp_filename = temp_file.name
        shutil.make_archive(temp_filename, format='zip', root_dir=folder)
        # Now overwrite the current multi-package xpi with the repackaged one.
        # Note that shutil.make_archive automatically added a '.zip' to the end
        # of the base_name provided as first argument.
        shutil.move(u'{0}.zip'.format(temp_filename), file_path)
        return u'\n'.join([unicode(num) for num in cert_serial_nums])
    finally:
        amo.utils.rm_local_tmp_dir(folder)
Exemple #3
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path,
                                 overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()
            # Make sure the internal XPIs aren't signed either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            assert self.file_.is_signed
            assert self.file_.cert_serial_num
            assert self.file_.hash
            # It's not the multi-package itself that is signed.
            assert not packaged.is_signed(self.file_.file_path)
            # It's the internal xpi.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And only the one that is an extension.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Exemple #4
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path,
                                 overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()
            # Make sure the internal XPIs aren't signed either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            assert self.file_.is_signed
            assert self.file_.cert_serial_num
            assert self.file_.hash
            # It's not the multi-package itself that is signed.
            assert not packaged.is_signed(self.file_.file_path)
            # It's the internal xpi.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                assert packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And only the one that is an extension.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Exemple #5
0
 def extract(self):
     """
     Will make all the directories and expand the files.
     Raises error on nasty files.
     """
     try:
         os.makedirs(self.dest)
     except OSError:
         return
     try:
         extract_xpi(self.src, self.dest)
     except Exception, err:
         task_log.error('Error (%s) extracting %s' % (err, self.src))
Exemple #6
0
 def extract(self):
     """
     Will make all the directories and expand the files.
     Raises error on nasty files.
     """
     try:
         os.makedirs(self.dest)
     except OSError:
         return
     try:
         extract_xpi(self.src, self.dest)
     except Exception, err:
         task_log.error('Error (%s) extracting %s' % (err, self.src))
Exemple #7
0
    def handle(self, *args, **options):
        success, fails, skipped = 0, 0, 0
        failed_ver_ids = []
        if options.get('dev'):
            _log('using dev IDs')
            ids = DEV_VERSION_IDS
        else:
            _log('using production IDs')
            ids = VERSION_IDS
        for version in Version.uncached.filter(pk__in=ids):
            try:
                if not old_version.search(version.version):
                    _log('skipped: Unexpected version: %s [%s]'
                         % (version.version, version.pk))
                    transaction.rollback()
                    skipped += 1
                    continue
                # eg. 1.0.1 -> 1.0.2
                new_ver_str = old_version.sub('.2', version.version)
                _log('version: %s [%s] -> %s' % (version, version.pk,
                                                 new_ver_str))
                version.version = new_ver_str
                version.version_int = None  # recalculate on save
                version.save()
                for file_ in version.files.all():
                    tmp = tempfile.mkdtemp()
                    try:
                        xpi_dir = os.path.join(tmp, 'xpi_dir')
                        os.mkdir(xpi_dir)
                        extract_xpi(file_.file_path, xpi_dir)
                        xpi = os.path.join(tmp, 'xpi.zip')
                        new_xpi = fix_xpi(xpi, xpi_dir, new_ver_str)
                        replace_xpi(file_, new_xpi, version)
                    finally:
                        shutil.rmtree(tmp)
            except:
                failed_ver_ids.append(version.pk)
                transaction.rollback()
                log.exception(' ** rollback()')
                fails += 1
            else:
                transaction.commit()
                success += 1

        _log('These versions failed: %s' % pprint.pformat(failed_ver_ids))
        _log('SUCCESS: %s' % success)
        _log('FAILS: %s' % fails)
        _log('SKIPPED: %s' % skipped)
        _log('TOTAL: %s' % (success + fails + skipped))
Exemple #8
0
    def handle(self, *args, **options):
        success, fails, skipped = 0, 0, 0
        failed_ver_ids = []
        if options.get('dev'):
            _log('using dev IDs')
            ids = DEV_VERSION_IDS
        else:
            _log('using production IDs')
            ids = VERSION_IDS
        for version in Version.uncached.filter(pk__in=ids):
            try:
                if not old_version.search(version.version):
                    _log('skipped: Unexpected version: %s [%s]' %
                         (version.version, version.pk))
                    transaction.rollback()
                    skipped += 1
                    continue
                # eg. 1.0.1 -> 1.0.2
                new_ver_str = old_version.sub('.2', version.version)
                _log('version: %s [%s] -> %s' %
                     (version, version.pk, new_ver_str))
                version.version = new_ver_str
                version.version_int = None  # recalculate on save
                version.save()
                for file_ in version.files.all():
                    tmp = tempfile.mkdtemp()
                    try:
                        xpi_dir = os.path.join(tmp, 'xpi_dir')
                        os.mkdir(xpi_dir)
                        extract_xpi(file_.file_path, xpi_dir)
                        xpi = os.path.join(tmp, 'xpi.zip')
                        new_xpi = fix_xpi(xpi, xpi_dir, new_ver_str)
                        replace_xpi(file_, new_xpi, version)
                    finally:
                        shutil.rmtree(tmp)
            except:
                failed_ver_ids.append(version.pk)
                transaction.rollback()
                log.exception(' ** rollback()')
                fails += 1
            else:
                transaction.commit()
                success += 1

        _log('These versions failed: %s' % pprint.pformat(failed_ver_ids))
        _log('SUCCESS: %s' % success)
        _log('FAILS: %s' % fails)
        _log('SKIPPED: %s' % skipped)
        _log('TOTAL: %s' % (success + fails + skipped))
Exemple #9
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file("apps/files/fixtures/files/multi-package.xpi", self.file_.file_path, overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            self.assert_not_signed()
            # The multi-package itself isn't signed.
            assert not packaged.is_signed(self.file_.file_path)
            # The internal extensions aren't either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                # The extension isn't.
                assert not packaged.is_signed(os.path.join(folder, "random_extension.xpi"))
                # And the theme isn't either.
                assert not packaged.is_signed(os.path.join(folder, "random_theme.xpi"))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Exemple #10
0
    def test_sign_file_multi_package(self):
        with amo.tests.copy_file('apps/files/fixtures/files/multi-package.xpi',
                                 self.file_.file_path, overwrite=True):
            self.file_.update(is_multi_package=True)
            self.assert_not_signed()

            packaged.sign_file(self.file_, settings.SIGNING_SERVER)
            self.assert_not_signed()
            # The multi-package itself isn't signed.
            assert not packaged.is_signed(self.file_.file_path)
            # The internal extensions aren't either.
            folder = tempfile.mkdtemp()
            try:
                extract_xpi(self.file_.file_path, folder)
                # The extension isn't.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_extension.xpi'))
                # And the theme isn't either.
                assert not packaged.is_signed(
                    os.path.join(folder, 'random_theme.xpi'))
            finally:
                amo.utils.rm_local_tmp_dir(folder)
Exemple #11
0
class FileViewer(object):
    """
    Provide access to a storage-managed file by copying it locally and
    extracting info from it. `src` is a storage-managed path and `dest` is a
    local temp path.
    """
    def __init__(self, file_obj):
        self.file = file_obj
        self.addon = self.file.version.addon
        self.src = (file_obj.guarded_file_path if file_obj.status
                    == amo.STATUS_DISABLED else file_obj.file_path)
        self.dest = os.path.join(settings.TMP_PATH, 'file_viewer',
                                 str(file_obj.pk))
        self._files, self.selected = None, None

    def __str__(self):
        return str(self.file.id)

    def _extraction_cache_key(self):
        return ('%s:file-viewer:extraction-in-progress:%s' %
                (settings.CACHE_PREFIX, self.file.id))

    def extract(self):
        """
        Will make all the directories and expand the files.
        Raises error on nasty files.
        """
        try:
            os.makedirs(os.path.dirname(self.dest))
        except OSError, err:
            pass

        # This is called `extract_xpi` but it unzips like a zip file.
        try:
            extract_xpi(self.src, self.dest, expand=True)
        except Exception, err:
            task_log.error('Error (%s) extracting %s' % (err, self.src))
            raise
Exemple #12
0
        try:
            os.makedirs(os.path.dirname(self.dest))
        except OSError, err:
            pass

        if self.is_search_engine() and self.src.endswith('.xml'):
            try:
                os.makedirs(self.dest)
            except OSError, err:
                pass
            copyfileobj(storage.open(self.src),
                        open(os.path.join(self.dest,
                                          self.file.filename), 'w'))
        else:
            try:
                extract_xpi(self.src, self.dest, expand=True)
            except Exception, err:
                task_log.error('Error (%s) extracting %s' % (err, self.src))
                raise

    def cleanup(self):
        if os.path.exists(self.dest):
            rm_local_tmp_dir(self.dest)

    def is_search_engine(self):
        """Is our file for a search engine?"""
        return self.file.version.addon.type == amo.ADDON_SEARCH

    def is_extracted(self):
        """If the file has been extracted or not."""
        return (os.path.exists(self.dest) and not
Exemple #13
0
        try:
            os.makedirs(os.path.dirname(self.dest))
        except OSError, err:
            pass

        if self.is_search_engine() and self.src.endswith('.xml'):
            try:
                os.makedirs(self.dest)
            except OSError, err:
                pass
            copyfileobj(storage.open(self.src),
                        open(os.path.join(self.dest,
                                          self.file.filename), 'w'))
        else:
            try:
                extract_xpi(self.src, self.dest, expand=True)
            except Exception, err:
                task_log.error('Error (%s) extracting %s' % (err, self.src))
                raise

    def cleanup(self):
        if os.path.exists(self.dest):
            rm_local_tmp_dir(self.dest)

    def is_search_engine(self):
        """Is our file for a search engine?"""
        return self.file.version.addon.type == amo.ADDON_SEARCH

    def is_extracted(self):
        """If the file has been extracted or not."""
        return (os.path.exists(self.dest) and not