2012-01-03 22:39:30 +01:00
|
|
|
#!/usr/bin/env python
|
2012-01-03 16:37:29 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# scanner.py - part of the FDroid server tools
|
|
|
|
# Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import re
|
|
|
|
import urllib
|
|
|
|
import time
|
|
|
|
import subprocess
|
2012-01-04 22:37:11 +01:00
|
|
|
import traceback
|
2012-01-03 16:37:29 +01:00
|
|
|
from optparse import OptionParser
|
|
|
|
import HTMLParser
|
|
|
|
import common
|
2012-01-03 22:39:30 +01:00
|
|
|
from common import BuildException
|
|
|
|
from common import VCSException
|
2012-01-03 16:37:29 +01:00
|
|
|
|
|
|
|
#Read configuration...
|
|
|
|
execfile('config.py')
|
|
|
|
|
|
|
|
|
|
|
|
# Parse command line...
|
|
|
|
parser = OptionParser()
|
|
|
|
parser.add_option("-v", "--verbose", action="store_true", default=False,
|
|
|
|
help="Spew out even more information than normal")
|
2012-01-04 22:37:11 +01:00
|
|
|
parser.add_option("-p", "--package", default=None,
|
|
|
|
help="Scan only the specified package")
|
2012-01-03 16:37:29 +01:00
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
|
|
|
|
# Get all apps...
|
|
|
|
apps = common.read_metadata(options.verbose)
|
|
|
|
|
|
|
|
html_parser = HTMLParser.HTMLParser()
|
|
|
|
|
|
|
|
problems = []
|
|
|
|
|
|
|
|
for app in apps:
|
|
|
|
|
2012-01-04 22:37:11 +01:00
|
|
|
skip = False
|
|
|
|
if options.package and app['id'] != options.package:
|
|
|
|
skip = True
|
2012-01-10 19:57:07 +01:00
|
|
|
elif app['Disabled']:
|
2012-01-03 16:37:29 +01:00
|
|
|
print "Skipping %s: disabled" % app['id']
|
2012-01-04 22:37:11 +01:00
|
|
|
skip = True
|
2012-01-03 16:37:29 +01:00
|
|
|
elif not app['builds']:
|
|
|
|
print "Skipping %s: no builds specified" % app['id']
|
2012-01-04 22:37:11 +01:00
|
|
|
skip = True
|
2012-01-03 16:37:29 +01:00
|
|
|
|
2012-01-04 22:37:11 +01:00
|
|
|
if not skip:
|
2012-01-03 16:37:29 +01:00
|
|
|
|
|
|
|
print "Processing " + app['id']
|
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
try:
|
2012-01-03 16:37:29 +01:00
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
build_dir = 'build/' + app['id']
|
2012-01-03 16:37:29 +01:00
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
# Set up vcs interface and make sure we have the latest code...
|
2012-01-10 19:57:07 +01:00
|
|
|
vcs = common.getvcs(app['Repo Type'], app['Repo'], build_dir)
|
2012-01-03 16:37:29 +01:00
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
refreshed_source = False
|
2012-01-03 16:37:29 +01:00
|
|
|
|
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
for thisbuild in app['builds']:
|
2012-01-03 16:37:29 +01:00
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
if thisbuild['commit'].startswith('!'):
|
|
|
|
print ("..skipping version " + thisbuild['version'] + " - " +
|
|
|
|
thisbuild['commit'][1:])
|
|
|
|
else:
|
|
|
|
print "..scanning version " + thisbuild['version']
|
|
|
|
|
|
|
|
# Prepare the source code...
|
|
|
|
root_dir = common.prepare_source(vcs, app, thisbuild,
|
2012-01-04 22:37:11 +01:00
|
|
|
build_dir, sdk_path, ndk_path, javacc_path,
|
2012-01-03 22:39:30 +01:00
|
|
|
not refreshed_source)
|
2012-01-03 16:37:29 +01:00
|
|
|
refreshed_source = True
|
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
# Scan for common known non-free blobs:
|
2012-01-04 22:37:11 +01:00
|
|
|
usual_suspects = ['flurryagent.jar',
|
|
|
|
'paypal_mpl.jar',
|
2012-01-25 21:21:28 +01:00
|
|
|
'libhoogleanalytics.jar',
|
|
|
|
'admob-sdk-android.jar',
|
|
|
|
'googleadview.jar']
|
2012-01-03 22:39:30 +01:00
|
|
|
for r,d,f in os.walk(build_dir):
|
|
|
|
for curfile in f:
|
|
|
|
if curfile.lower() in usual_suspects:
|
2012-01-04 22:37:11 +01:00
|
|
|
msg = 'Found probable non-free blob ' + os.path.join(r, curfile)
|
2012-01-03 22:39:30 +01:00
|
|
|
msg += ' in ' + app['id'] + ' ' + thisbuild['version']
|
|
|
|
problems.append(msg)
|
|
|
|
|
2012-01-13 20:28:49 +01:00
|
|
|
# Presence of a jni directory without buildjni=yes might
|
|
|
|
# indicate a problem...
|
|
|
|
if (os.path.exists(os.path.join(root_dir, 'jni')) and
|
|
|
|
thisbuild.get('buildjni', 'no') != 'yes'):
|
|
|
|
msg = 'Found jni directory, but buildjni is not enabled'
|
|
|
|
msg += ' in ' + app['id'] + ' ' + thisbuild['version']
|
|
|
|
problems.append(msg)
|
|
|
|
|
2012-01-03 22:39:30 +01:00
|
|
|
except BuildException as be:
|
|
|
|
msg = "Could not scan app %s due to BuildException: %s" % (app['id'], be)
|
|
|
|
problems.append(msg)
|
|
|
|
except VCSException as vcse:
|
|
|
|
msg = "VCS error while scanning app %s: %s" % (app['id'], vcse)
|
|
|
|
problems.append(msg)
|
2012-01-04 22:37:11 +01:00
|
|
|
except Exception:
|
|
|
|
msg = "Could not scan app %s due to unknown error: %s" % (app['id'], traceback.format_exc())
|
2012-01-03 22:39:30 +01:00
|
|
|
problems.append(msg)
|
2012-01-03 16:37:29 +01:00
|
|
|
|
|
|
|
print "Finished:"
|
|
|
|
for problem in problems:
|
|
|
|
print problem
|
|
|
|
print str(len(problems)) + ' problems.'
|
|
|
|
|