コード例 #1
0
ファイル: tasks.py プロジェクト: nothingisdead/addons-server
def check_for_api_keys_in_file(results, upload):
    if upload.addon:
        users = upload.addon.authors.all()
    else:
        users = [upload.user] if upload.user else []

    keys = []
    for user in users:
        try:
            key = APIKey.get_jwt_key(user_id=user.id)
            keys.append(key)
        except APIKey.DoesNotExist:
            pass

    if len(keys) > 0:
        zipfile = SafeZip(source=upload.path)
        zipfile.is_valid()
        for zipinfo in zipfile.info_list:
            if zipinfo.file_size >= 64:
                file_ = zipfile.read(zipinfo)
                for key in keys:
                    if key.secret in file_.decode(encoding='unicode-escape',
                                                  errors="ignore"):
                        log.info('Developer API key for user %s found in '
                                 'submission.' % key.user)
                        if key.user == upload.user:
                            msg = ugettext('Your developer API key was found '
                                           'in the submitted file. To protect '
                                           'your account, the key will be '
                                           'revoked.')
                        else:
                            msg = ugettext('The developer API key of a '
                                           'coauthor was found in the '
                                           'submitted file. To protect your '
                                           'add-on, the key will be revoked.')
                        insert_validation_message(results,
                                                  type_='error',
                                                  message=msg,
                                                  msg_id='api_key_detected',
                                                  compatibility_type=None)

                        # Revoke after 2 minutes to allow the developer to
                        # fetch the validation results
                        revoke_api_key.apply_async(kwargs={'key_id': key.id},
                                                   countdown=120)
        zipfile.close()

    return results
コード例 #2
0
ファイル: utils.py プロジェクト: eviljeff/olympia
def rezip_file(response, pk):
    # An .xpi does not have a directory inside the zip, yet zips from github
    # do, so we'll need to rezip the file before passing it through to the
    # validator.
    loc = os.path.join(user_media_path('addons'), 'temp', uuid.uuid4().hex)
    old_filename = '{}_github_webhook.zip'.format(pk)
    old_path = os.path.join(loc, old_filename)

    with storage.open(old_path, 'wb') as old:
        old.write(response.content)

    new_filename = '{}_github_webhook.xpi'.format(pk)
    new_path = os.path.join(loc, new_filename)

    old_zip = SafeZip(old_path)
    if not old_zip.is_valid():
        raise

    with storage.open(new_path, 'w') as new:
        new_zip = zipfile.ZipFile(new, 'w')

        for obj in old_zip.filelist:
            # Basically strip off the leading directory.
            new_filename = obj.filename.partition('/')[-1]
            if not new_filename:
                continue
            new_zip.writestr(new_filename, old_zip.read(obj.filename))

        new_zip.close()

    old_zip.close()
    return new_path
コード例 #3
0
def rezip_file(response, pk):
    # An .xpi does not have a directory inside the zip, yet zips from github
    # do, so we'll need to rezip the file before passing it through to the
    # validator.
    loc = os.path.join(user_media_path('addons'), 'temp', uuid.uuid4().hex)
    old_filename = '{}_github_webhook.zip'.format(pk)
    old_path = os.path.join(loc, old_filename)

    with storage.open(old_path, 'wb') as old:
        old.write(response.content)

    new_filename = '{}_github_webhook.xpi'.format(pk)
    new_path = os.path.join(loc, new_filename)

    old_zip = SafeZip(old_path)
    if not old_zip.is_valid():
        raise

    with storage.open(new_path, 'w') as new:
        new_zip = zipfile.ZipFile(new, 'w')

        for obj in old_zip.filelist:
            # Basically strip off the leading directory.
            new_filename = obj.filename.partition('/')[-1]
            if not new_filename:
                continue
            new_zip.writestr(new_filename, old_zip.read(obj.filename))

        new_zip.close()

    old_zip.close()
    return new_path
コード例 #4
0
ファイル: utils.py プロジェクト: ravsa/addons-server
def build_webext_dictionary_from_legacy(addon, destination):
    """Create a webext package of a legacy dictionary `addon`, and put it in
    `destination` path."""
    from olympia.files.utils import SafeZip  # Avoid circular import.
    old_path = addon.current_version.all_files[0].file_path
    old_zip = SafeZip(old_path)
    if not old_zip.is_valid():
        raise ValidationError('Current dictionary xpi is not valid')

    if not addon.target_locale:
        raise ValidationError('Addon has no target_locale')

    dictionary_path = ''

    with zipfile.ZipFile(destination, 'w', zipfile.ZIP_DEFLATED) as new_zip:
        for obj in old_zip.filelist:
            splitted = obj.filename.split('/')
            # Ignore useless directories and files.
            if splitted[0] in ('META-INF', '__MACOSX', 'chrome',
                               'chrome.manifest', 'install.rdf'):
                continue

            # Also ignore javascript (regardless of where they are, not just at
            # the root), since dictionaries should not contain any code.
            if splitted[-1].endswith('.js'):
                continue

            # Store the path of the last .dic file we find. It can be inside a
            # directory.
            if (splitted[-1].endswith('.dic')):
                dictionary_path = obj.filename

            new_zip.writestr(obj.filename, old_zip.read(obj.filename))

        # Now that all files we want from the old zip are copied, build and
        # add manifest.json.
        if not dictionary_path:
            # This should not happen... It likely means it's an invalid
            # dictionary to begin with, or one that has its .dic file in a
            # chrome/ directory for some reason. Abort!
            raise ValidationError('Current dictionary xpi has no .dic file')

        # Dumb version number increment. This will be invalid in some cases,
        # but some of the dictionaries we have currently already have wild
        # version numbers anyway.
        version_number = addon.current_version.version
        if version_number.endswith('.1-typefix'):
            version_number = version_number.replace('.1-typefix', '.2webext')
        else:
            version_number = '%s.1webext' % version_number

        manifest = {
            'manifest_version': 2,
            'name': unicode(addon.name),
            'version': version_number,
            'dictionaries': {addon.target_locale: dictionary_path},
        }

        # Write manifest.json we just build.
        new_zip.writestr('manifest.json', json.dumps(manifest))
コード例 #5
0
ファイル: tasks.py プロジェクト: eviljeff/olympia
def check_for_api_keys_in_file(results, upload):
    if upload.addon:
        users = upload.addon.authors.all()
    else:
        users = [upload.user] if upload.user else []

    keys = []
    for user in users:
        try:
            key = APIKey.get_jwt_key(user_id=user.id)
            keys.append(key)
        except APIKey.DoesNotExist:
            pass

    if len(keys) > 0:
        zipfile = SafeZip(source=upload.path)
        zipfile.is_valid()
        for zipinfo in zipfile.info_list:
            if zipinfo.file_size >= 64:
                file_ = zipfile.read(zipinfo)
                for key in keys:
                    if key.secret in file_.decode(encoding='unicode-escape',
                                                  errors="ignore"):
                        log.info('Developer API key for user %s found in '
                                 'submission.' % key.user)
                        if key.user == upload.user:
                            msg = ugettext('Your developer API key was found '
                                           'in the submitted file. To protect '
                                           'your account, the key will be '
                                           'revoked.')
                        else:
                            msg = ugettext('The developer API key of a '
                                           'coauthor was found in the '
                                           'submitted file. To protect your '
                                           'add-on, the key will be revoked.')
                        insert_validation_message(
                            results, type_='error',
                            message=msg, msg_id='api_key_detected',
                            compatibility_type=None)

                        # Revoke after 2 minutes to allow the developer to
                        # fetch the validation results
                        revoke_api_key.apply_async(
                            kwargs={'key_id': key.id}, countdown=120)
        zipfile.close()

    return results
コード例 #6
0
    def get_localepicker(self):
        """
        For a file that is part of a language pack, extract
        the chrome/localepicker.properties file and return as
        a string.
        """
        start = time.time()
        zip = SafeZip(self.file_path, raise_on_failure=False)
        if not zip.is_valid():
            return ''

        try:
            manifest = zip.read('chrome.manifest')
        except KeyError, e:
            log.info('No file named: chrome.manifest in file: %s' % self.pk)
            return ''
コード例 #7
0
    def get_localepicker(self):
        """
        For a file that is part of a language pack, extract
        the chrome/localepicker.properties file and return as
        a string.
        """
        start = time.time()
        zip = SafeZip(self.file_path, raise_on_failure=False)
        if not zip.is_valid():
            return ''

        try:
            manifest = zip.read('chrome.manifest')
        except KeyError, e:
            log.info('No file named: chrome.manifest in file: %s' % self.pk)
            return ''
コード例 #8
0
ファイル: models.py プロジェクト: eviljeff/olympia
    def get_localepicker(self):
        """
        For a file that is part of a language pack, extract
        the chrome/localepicker.properties file and return as
        a string.
        """
        start = time.time()
        zip = SafeZip(self.file_path, validate=False)

        try:
            is_valid = zip.is_valid()
        except (zipfile.BadZipfile, IOError):
            is_valid = False

        if not is_valid:
            return ''

        try:
            manifest = zip.read('chrome.manifest')
        except KeyError as e:
            log.info('No file named: chrome.manifest in file: %s' % self.pk)
            return ''

        res = self._get_localepicker.search(manifest)
        if not res:
            log.error('Locale browser not in chrome.manifest: %s' % self.pk)
            return ''

        try:
            p = res.groups()[1]
            if 'localepicker.properties' not in p:
                p = os.path.join(p, 'localepicker.properties')
            res = zip.extract_from_manifest(p)
        except (zipfile.BadZipfile, IOError) as e:
            log.error('Error unzipping: %s, %s in file: %s' % (p, e, self.pk))
            return ''
        except (ValueError, KeyError) as e:
            log.error('No file named: %s in file: %s' % (e, self.pk))
            return ''

        end = time.time() - start
        log.info('Extracted localepicker file: %s in %.2fs' %
                 (self.pk, end))
        statsd.timing('files.extract.localepicker', (end * 1000))
        return res
コード例 #9
0
ファイル: models.py プロジェクト: ryanleesipes/addons-server
    def get_localepicker(self):
        """
        For a file that is part of a language pack, extract
        the chrome/localepicker.properties file and return as
        a string.
        """
        start = time.time()
        zip = SafeZip(self.file_path, validate=False)

        try:
            is_valid = zip.is_valid()
        except (zipfile.BadZipfile, IOError):
            is_valid = False

        if not is_valid:
            return ''

        try:
            manifest = zip.read('chrome.manifest')
        except KeyError as e:
            log.info('No file named: chrome.manifest in file: %s' % self.pk)
            return ''

        res = self._get_localepicker.search(manifest)
        if not res:
            log.error('Locale browser not in chrome.manifest: %s' % self.pk)
            return ''

        try:
            p = res.groups()[1]
            if 'localepicker.properties' not in p:
                p = os.path.join(p, 'localepicker.properties')
            res = zip.extract_from_manifest(p)
        except (zipfile.BadZipfile, IOError) as e:
            log.error('Error unzipping: %s, %s in file: %s' % (p, e, self.pk))
            return ''
        except (ValueError, KeyError) as e:
            log.error('No file named: %s in file: %s' % (e, self.pk))
            return ''

        end = time.time() - start
        log.info('Extracted localepicker file: %s in %.2fs' %
                 (self.pk, end))
        statsd.timing('files.extract.localepicker', (end * 1000))
        return res
コード例 #10
0
 def test_is_broken(self):
     zip_file = SafeZip(self.xpi_path('signed'))
     zip_file.is_valid()
     zip_file.info_list[2].filename = 'META-INF/foo.sf'
     assert not zip_file.is_signed()
コード例 #11
0
 def test_is_secure(self):
     zip_file = SafeZip(self.xpi_path('signed'))
     zip_file.is_valid()
     assert zip_file.is_signed()
コード例 #12
0
 def test_not_secure(self):
     zip_file = SafeZip(self.xpi_path('extension'))
     zip_file.is_valid()
     assert not zip_file.is_signed()
コード例 #13
0
 def test_read(self):
     zip_file = SafeZip(self.xpi_path('langpack-localepicker'))
     assert zip_file.is_valid()
     assert 'locale browser de' in zip_file.read('chrome.manifest')
コード例 #14
0
 def test_unzip_not_fatal(self):
     zip_file = SafeZip(self.xpi_path('search.xml'), raise_on_failure=False)
     assert not zip_file.is_valid()
コード例 #15
0
ファイル: test_helpers.py プロジェクト: renopey/addons-server
 def test_unzip_not_fatal(self):
     zip_file = SafeZip(self.xpi_path('search.xml'), raise_on_failure=False)
     assert not zip_file.is_valid()
コード例 #16
0
 def test_read(self):
     zip_file = SafeZip(self.xpi_path('langpack-localepicker'))
     assert zip_file.is_valid()
     assert 'locale browser de' in zip_file.read('chrome.manifest')
コード例 #17
0
 def test_is_broken(self):
     zip_file = SafeZip(self.xpi_path('signed'))
     zip_file.is_valid()
     zip_file.info_list[2].filename = 'META-INF/foo.sf'
     assert not zip_file.is_signed()
コード例 #18
0
 def test_is_secure(self):
     zip_file = SafeZip(self.xpi_path('signed'))
     zip_file.is_valid()
     assert zip_file.is_signed()
コード例 #19
0
 def test_not_secure(self):
     zip_file = SafeZip(self.xpi_path('extension'))
     zip_file.is_valid()
     assert not zip_file.is_signed()