diff --git a/Privileged-F-Droid/src/main/AndroidManifest.xml b/Privileged-F-Droid/src/main/AndroidManifest.xml
index 63bf561ed..e919ee606 100644
--- a/Privileged-F-Droid/src/main/AndroidManifest.xml
+++ b/Privileged-F-Droid/src/main/AndroidManifest.xml
@@ -11,6 +11,14 @@
android:name="android.permission.DELETE_PACKAGES"
tools:ignore="ProtectedPermissions" />
+
+
+
+ android:permission="org.fdroid.fdroid.privileged.USE_SERVICE">
diff --git a/Privileged-F-Droid/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java b/Privileged-F-Droid/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
index b727e7408..d717d4b8d 100644
--- a/Privileged-F-Droid/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
+++ b/Privileged-F-Droid/src/main/java/org/fdroid/fdroid/privileged/PrivilegedService.java
@@ -19,40 +19,25 @@
package org.fdroid.fdroid.privileged;
-import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.Signature;
import android.net.Uri;
-import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.lang.reflect.Method;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
/**
* This service provides an API via AIDL IPC for the main F-Droid app to install/delete packages.
- *
- * Security:
- * Binding only works when,...
- * - packageName is "org.fdroid.fdroid"
- * - signature is equal or BuildConfig.DEBUG
*/
public class PrivilegedService extends Service {
public static final String TAG = "PrivilegedFDroid";
- private static final String F_DROID_PACKAGE = "org.fdroid.fdroid";
-
private Method mInstallMethod;
private Method mDeleteMethod;
@@ -119,16 +104,12 @@ public class PrivilegedService extends Service {
@Override
public void installPackage(Uri packageURI, int flags, String installerPackageName,
IPrivilegedCallback callback) {
- if (isAllowed()) {
- installPackageImpl(packageURI, flags, installerPackageName, callback);
- }
+ installPackageImpl(packageURI, flags, installerPackageName, callback);
}
@Override
public void deletePackage(String packageName, int flags, IPrivilegedCallback callback) {
- if (isAllowed()) {
- deletePackageImpl(packageName, flags, callback);
- }
+ deletePackageImpl(packageName, flags, callback);
}
};
@@ -137,111 +118,6 @@ public class PrivilegedService extends Service {
return mBinder;
}
- private boolean isAllowed() {
- // Check that binding app is allowed to use this API
- try {
-
- barrierPackageName();
- barrierPackageCertificate();
-
- } catch (WrongPackageCertificateException e) {
- Log.e(TAG, "package certificate is not allowed!", e);
- return false;
- } catch (WrongPackageNameException e) {
- Log.e(TAG, "package name is not allowed!", e);
- return false;
- }
-
- return true;
- }
-
- /**
- * Checks if process that binds to this service (i.e. the package name corresponding to the
- * process) is allowed. Only returns when package name is allowed!
- *
- * @throws WrongPackageNameException
- */
- private void barrierPackageName() throws WrongPackageNameException {
- int uid = Binder.getCallingUid();
- String[] callingPackages = getPackageManager().getPackagesForUid(uid);
-
- // is calling package allowed to use this service?
- for (String currentPkg : callingPackages) {
- if (F_DROID_PACKAGE.equals(currentPkg)) {
- return;
- }
- }
-
- throw new WrongPackageNameException("package name is not allowed");
- }
-
- private void barrierPackageCertificate() throws WrongPackageCertificateException {
- String packageName = getCurrentCallingPackage();
-
- byte[] packageCertificate;
- try {
- packageCertificate = getPackageCertificate(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- throw new WrongPackageCertificateException(e.getMessage());
- }
-
- MessageDigest md;
- try {
- md = MessageDigest.getInstance("SHA-512");
- } catch (NoSuchAlgorithmException e) {
- throw new WrongPackageCertificateException("SHA-512 not available!");
- }
- byte[] hash = md.digest(packageCertificate);
-
- Log.d(TAG, "hash:" + getHex(hash));
- Log.d(TAG, "F_DROID_CERT_SHA512:" + BuildConfig.F_DROID_CERT_SHA512);
-
- if (getHex(hash).equals(BuildConfig.F_DROID_CERT_SHA512)
- || BuildConfig.DEBUG) {
- return;
- }
-
- throw new WrongPackageCertificateException("certificate not allowed!");
- }
-
- private byte[] getPackageCertificate(String packageName) throws PackageManager.NameNotFoundException {
- // we do check the byte array of *all* signatures
- @SuppressLint("PackageManagerGetSignatures")
- PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
-
- // NOTE: Silly Android API naming: Signatures are actually certificates
- Signature[] certificates = pkgInfo.signatures;
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- for (Signature cert : certificates) {
- try {
- outputStream.write(cert.toByteArray());
- } catch (IOException e) {
- throw new RuntimeException("Should not happen! Writing ByteArrayOutputStream to concat certificates failed");
- }
- }
-
- // Even if an apk has several certificates, these certificates should never change
- // Google Play does not allow the introduction of new certificates into an existing apk
- // Also see this attack: http://stackoverflow.com/a/10567852
- return outputStream.toByteArray();
- }
-
- /**
- * Returns package name associated with the UID, which is assigned to the process that sent you the
- * current transaction that is being processed :)
- *
- * @return package name
- */
- protected String getCurrentCallingPackage() {
- String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
-
- // NOTE: No support for sharedUserIds
- // callingPackages contains more than one entry when sharedUserId has been used
- // No plans to support sharedUserIds due to many bugs connected to them:
- // http://java-hamster.blogspot.de/2010/05/androids-shareduserid.html
- return callingPackages[0];
- }
-
@Override
public void onCreate() {
super.onCreate();
@@ -266,40 +142,4 @@ public class PrivilegedService extends Service {
}
}
- private String getHex(byte[] byteData) {
- StringBuilder hexString = new StringBuilder();
- for (byte aByteData : byteData) {
- String hex = Integer.toHexString(0xff & aByteData);
- if (hex.length() == 1) {
- hexString.append('0');
- }
- hexString.append(hex);
- }
-
- return hexString.toString();
- }
-
- public static class WrongPackageCertificateException extends Exception {
- private static final long serialVersionUID = -1294642703122196028L;
-
- public WrongPackageCertificateException(String message) {
- super(message);
- }
- }
-
- public static class WrongPackageNameException extends Exception {
- private static final long serialVersionUID = -2294642703111196028L;
-
- public WrongPackageNameException(String message) {
- super(message);
- }
- }
-
- public static class AndroidNotCompatibleException extends Exception {
- private static final long serialVersionUID = -3294642703111196028L;
-
- public AndroidNotCompatibleException(String message) {
- super(message);
- }
- }
}