diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-12 21:53:24 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-12 21:53:24 -0700 |
commit | d0fc3dded203fcd9406914c79ace4abd2b56fe56 (patch) | |
tree | bfcf7ebad35452e0c4aba005ba53356afa4cf542 | |
parent | 168173a698e820ceb1ebf54b4910888891be2056 (diff) | |
parent | 766cbfe44be3c5013a6a22bd6cd8ad1055a37256 (diff) | |
download | frameworks_base-d0fc3dded203fcd9406914c79ace4abd2b56fe56.zip frameworks_base-d0fc3dded203fcd9406914c79ace4abd2b56fe56.tar.gz frameworks_base-d0fc3dded203fcd9406914c79ace4abd2b56fe56.tar.bz2 |
Merge change 21044
* changes:
Add new API to compare certs of two UIDs.
-rw-r--r-- | api/current.xml | 30 | ||||
-rw-r--r-- | core/java/android/app/ApplicationContext.java | 9 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 2 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 29 | ||||
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 55 | ||||
-rw-r--r-- | test-runner/android/test/mock/MockPackageManager.java | 5 |
6 files changed, 119 insertions, 11 deletions
diff --git a/api/current.xml b/api/current.xml index c179789..2777210 100644 --- a/api/current.xml +++ b/api/current.xml @@ -37880,6 +37880,21 @@ <parameter name="pkg2" type="java.lang.String"> </parameter> </method> +<method name="checkSignatures" + return="int" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="uid1" type="int"> +</parameter> +<parameter name="uid2" type="int"> +</parameter> +</method> <method name="clearPackagePreferredActivities" return="void" abstract="true" @@ -121998,6 +122013,21 @@ <parameter name="pkg2" type="java.lang.String"> </parameter> </method> +<method name="checkSignatures" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="uid1" type="int"> +</parameter> +<parameter name="uid2" type="int"> +</parameter> +</method> <method name="clearPackagePreferredActivities" return="void" abstract="false" diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 7e71088..a74fbe4 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -1664,6 +1664,15 @@ class ApplicationContext extends Context { } @Override + public int checkSignatures(int uid1, int uid2) { + try { + return mPM.checkUidSignatures(uid1, uid2); + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + } + + @Override public String[] getPackagesForUid(int uid) { try { return mPM.getPackagesForUid(uid); diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index d9f298d..7760612 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -75,6 +75,8 @@ interface IPackageManager { int checkSignatures(String pkg1, String pkg2); + int checkUidSignatures(int uid1, int uid2); + String[] getPackagesForUid(int uid); String getNameForUid(int uid); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index bca1715..3a178a1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -865,6 +865,7 @@ public abstract class PackageManager { * {@link #SIGNATURE_SECOND_NOT_SIGNED}, {@link #SIGNATURE_NO_MATCH}, * or {@link #SIGNATURE_UNKNOWN_PACKAGE}. * + * @see #checkSignatures(int, int) * @see #SIGNATURE_MATCH * @see #SIGNATURE_NEITHER_SIGNED * @see #SIGNATURE_FIRST_NOT_SIGNED @@ -875,6 +876,34 @@ public abstract class PackageManager { public abstract int checkSignatures(String pkg1, String pkg2); /** + * Like {@link #checkSignatures(String, String)}, but takes UIDs of + * the two packages to be checked. This can be useful, for example, + * when doing the check in an IPC, where the UID is the only identity + * available. It is functionally identical to determining the package + * associated with the UIDs and checking their signatures. + * + * @param pkg1 First UID whose signature will be compared. + * @param pkg2 Second UID whose signature will be compared. + * @return Returns an integer indicating whether there is a matching + * signature: the value is >= 0 if there is a match (or neither package + * is signed), or < 0 if there is not a match. The match result can be + * further distinguished with the success (>= 0) constants + * {@link #SIGNATURE_MATCH}, {@link #SIGNATURE_NEITHER_SIGNED}; or + * failure (< 0) constants {@link #SIGNATURE_FIRST_NOT_SIGNED}, + * {@link #SIGNATURE_SECOND_NOT_SIGNED}, {@link #SIGNATURE_NO_MATCH}, + * or {@link #SIGNATURE_UNKNOWN_PACKAGE}. + * + * @see #checkSignatures(int, int) + * @see #SIGNATURE_MATCH + * @see #SIGNATURE_NEITHER_SIGNED + * @see #SIGNATURE_FIRST_NOT_SIGNED + * @see #SIGNATURE_SECOND_NOT_SIGNED + * @see #SIGNATURE_NO_MATCH + * @see #SIGNATURE_UNKNOWN_PACKAGE + */ + public abstract int checkSignatures(int uid1, int uid2); + + /** * Retrieve the names of all packages that are associated with a particular * user id. In most cases, this will be a single package name, the package * that has been assigned that user id. Where there are multiple packages diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index e14f805..aac13b6 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1138,25 +1138,57 @@ class PackageManagerService extends IPackageManager.Stub { || p2 == null || p2.mExtras == null) { return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; } - return checkSignaturesLP(p1, p2); + return checkSignaturesLP(p1.mSignatures, p2.mSignatures); } } - int checkSignaturesLP(PackageParser.Package p1, PackageParser.Package p2) { - if (p1.mSignatures == null) { - return p2.mSignatures == null + public int checkUidSignatures(int uid1, int uid2) { + synchronized (mPackages) { + Signature[] s1; + Signature[] s2; + Object obj = mSettings.getUserIdLP(uid1); + if (obj != null) { + if (obj instanceof SharedUserSetting) { + s1 = ((SharedUserSetting)obj).signatures.mSignatures; + } else if (obj instanceof PackageSetting) { + s1 = ((PackageSetting)obj).signatures.mSignatures; + } else { + return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; + } + } else { + return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; + } + obj = mSettings.getUserIdLP(uid2); + if (obj != null) { + if (obj instanceof SharedUserSetting) { + s2 = ((SharedUserSetting)obj).signatures.mSignatures; + } else if (obj instanceof PackageSetting) { + s2 = ((PackageSetting)obj).signatures.mSignatures; + } else { + return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; + } + } else { + return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; + } + return checkSignaturesLP(s1, s2); + } + } + + int checkSignaturesLP(Signature[] s1, Signature[] s2) { + if (s1 == null) { + return s2 == null ? PackageManager.SIGNATURE_NEITHER_SIGNED : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; } - if (p2.mSignatures == null) { + if (s2 == null) { return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; } - final int N1 = p1.mSignatures.length; - final int N2 = p2.mSignatures.length; + final int N1 = s1.length; + final int N2 = s2.length; for (int i=0; i<N1; i++) { boolean match = false; for (int j=0; j<N2; j++) { - if (p1.mSignatures[i].equals(p2.mSignatures[j])) { + if (s1[i].equals(s2[j])) { match = true; break; } @@ -2907,9 +2939,9 @@ class PackageManagerService extends IPackageManager.Stub { allowed = true; } else if (p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE || p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { - allowed = (checkSignaturesLP(p.owner, pkg) + allowed = (checkSignaturesLP(p.owner.mSignatures, pkg.mSignatures) == PackageManager.SIGNATURE_MATCH) - || (checkSignaturesLP(mPlatformPackage, pkg) + || (checkSignaturesLP(mPlatformPackage.mSignatures, pkg.mSignatures) == PackageManager.SIGNATURE_MATCH); if (p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { @@ -3556,7 +3588,8 @@ class PackageManagerService extends IPackageManager.Stub { // First find the old package info and check signatures synchronized(mPackages) { oldPackage = mPackages.get(pkgName); - if(checkSignaturesLP(pkg, oldPackage) != PackageManager.SIGNATURE_MATCH) { + if(checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures) + != PackageManager.SIGNATURE_MATCH) { res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return; } diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java index 63a177e..4a50c5d 100644 --- a/test-runner/android/test/mock/MockPackageManager.java +++ b/test-runner/android/test/mock/MockPackageManager.java @@ -139,6 +139,11 @@ public class MockPackageManager extends PackageManager { } @Override + public int checkSignatures(int uid1, int uid2) { + throw new UnsupportedOperationException(); + } + + @Override public String[] getPackagesForUid(int uid) { throw new UnsupportedOperationException(); } |