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)
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)
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)
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))
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))
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)
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)
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
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