diff options
author | Suchi Amalapurapu <asuchitra@google.com> | 2010-03-31 23:22:56 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-03-31 23:22:56 -0700 |
commit | 392be3fa3d7c5e33ddb1dd85893bc4eaee170252 (patch) | |
tree | 5975a21f7ed93826414d0affdaa8adf205e5415f /services/java/com/android/server/PackageManagerService.java | |
parent | d4afde3d12dd0320b64d3bf26bf805aafa09395c (diff) | |
parent | 1aa64b53eb9b3cc7904705076a015a5cd0e3b536 (diff) | |
download | frameworks_base-392be3fa3d7c5e33ddb1dd85893bc4eaee170252.zip frameworks_base-392be3fa3d7c5e33ddb1dd85893bc4eaee170252.tar.gz frameworks_base-392be3fa3d7c5e33ddb1dd85893bc4eaee170252.tar.bz2 |
am 1aa64b53: am ae18171a: Change certificate policy.
Merge commit '1aa64b53eb9b3cc7904705076a015a5cd0e3b536' into kraken
* commit '1aa64b53eb9b3cc7904705076a015a5cd0e3b536':
Change certificate policy.
Diffstat (limited to 'services/java/com/android/server/PackageManagerService.java')
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 249 |
1 files changed, 69 insertions, 180 deletions
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 9e0f0ed..8c4bca9 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1835,21 +1835,19 @@ class PackageManagerService extends IPackageManager.Stub { if (s2 == null) { return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; } - 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 (s1[i].equals(s2[j])) { - match = true; - break; - } - } - if (!match) { - return PackageManager.SIGNATURE_NO_MATCH; - } + HashSet<Signature> set1 = new HashSet<Signature>(); + for (Signature sig : s1) { + set1.add(sig); + } + HashSet<Signature> set2 = new HashSet<Signature>(); + for (Signature sig : s2) { + set2.add(sig); } - return PackageManager.SIGNATURE_MATCH; + // Make sure s2 contains all signatures in s1. + if (set1.equals(set2)) { + return PackageManager.SIGNATURE_MATCH; + } + return PackageManager.SIGNATURE_NO_MATCH; } public String[] getPackagesForUid(int uid) { @@ -2501,6 +2499,9 @@ class PackageManagerService extends IPackageManager.Stub { mLastScanError = pp.getParseError(); return false; } + } else { + // Lets implicitly assign existing certificates. + pkg.mSignatures = ps.signatures.mSignatures; } } return true; @@ -2629,28 +2630,27 @@ class PackageManagerService extends IPackageManager.Stub { } private boolean verifySignaturesLP(PackageSetting pkgSetting, - PackageParser.Package pkg, int parseFlags, boolean updateSignature) { - if (pkg.mSignatures != null) { - if (!pkgSetting.signatures.updateSignatures(pkg.mSignatures, - updateSignature)) { - Slog.e(TAG, "Package " + pkg.packageName - + " signatures do not match the previously installed version; ignoring!"); - mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; - return false; - } - - if (pkgSetting.sharedUser != null) { - if (!pkgSetting.sharedUser.signatures.mergeSignatures( - pkg.mSignatures, updateSignature)) { + PackageParser.Package pkg) { + if (pkgSetting.signatures.mSignatures != null) { + // Already existing package. Make sure signatures match + if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) != + PackageManager.SIGNATURE_MATCH) { Slog.e(TAG, "Package " + pkg.packageName - + " has no signatures that match those in shared user " - + pkgSetting.sharedUser.name + "; ignoring!"); - mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; + + " signatures do not match the previously installed version; ignoring!"); + mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; return false; } + } + // Check for shared user signatures + if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { + if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, + pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { + Slog.e(TAG, "Package " + pkg.packageName + + " has no signatures that match those in shared user " + + pkgSetting.sharedUser.name + "; ignoring!"); + mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; + return false; } - } else { - pkg.mSignatures = pkgSetting.signatures.mSignatures; } return true; } @@ -2996,10 +2996,8 @@ class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.uid = pkgSetting.userId; pkg.mExtras = pkgSetting; - if (!verifySignaturesLP(pkgSetting, pkg, parseFlags, - (scanMode&SCAN_UPDATE_SIGNATURE) != 0)) { + if (!verifySignaturesLP(pkgSetting, pkg)) { if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { - mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; return null; } // The signature has changed, but this package is in the system @@ -3011,8 +3009,9 @@ class PackageManagerService extends IPackageManager.Stub { // associated with an overall shared user, which doesn't seem all // that unreasonable. if (pkgSetting.sharedUser != null) { - if (!pkgSetting.sharedUser.signatures.mergeSignatures( - pkg.mSignatures, false)) { + if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, + pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { + Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return null; } @@ -5543,7 +5542,7 @@ class PackageManagerService extends IPackageManager.Stub { // First find the old package info and check signatures synchronized(mPackages) { oldPackage = mPackages.get(pkgName); - if (checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures) + if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return; @@ -5571,7 +5570,6 @@ class PackageManagerService extends IPackageManager.Stub { oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName); } - parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING; // First delete the existing package while retaining the data directory if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA, res.removedInfo)) { @@ -5595,20 +5593,7 @@ class PackageManagerService extends IPackageManager.Stub { } } - if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { - // If we deleted an exisiting package, the old source and resource files that we - // were keeping around in case we needed them (see below) can now be deleted. - // This info will be set on the res.removedInfo to clean up later on as post - // install action. - - //update signature on the new package setting - //this should always succeed, since we checked the - //signature earlier. - synchronized(mPackages) { - verifySignaturesLP(mSettings.mPackages.get(pkgName), pkg, - parseFlags, true); - } - } else { + if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { // remove package from internal structures. Note that we want deletePackageX to // delete the package data and cache directories that it created in // scanPackageLocked, unless those directories existed before we even tried to @@ -5627,19 +5612,23 @@ class PackageManagerService extends IPackageManager.Stub { Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName); return; } - PackageInstalledInfo restoreRes = new PackageInstalledInfo(); - restoreRes.removedInfo = new PackageRemovedInfo(); // Parse old package - parseFlags &= ~PackageManager.INSTALL_REPLACE_EXISTING; - scanPackageLI(restoreFile, parseFlags, scanMode); + boolean oldOnSd = isExternal(deletedPackage); + int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | + (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | + (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); + int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE; + if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode) == null) { + Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); + return; + } + // Restore of old package succeeded. Update permissions. synchronized (mPackages) { updatePermissionsLP(deletedPackage.packageName, deletedPackage, true, false); mSettings.writeLP(); } - if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) { - Slog.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade"); - } + Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); } } } @@ -5691,15 +5680,7 @@ class PackageManagerService extends IPackageManager.Stub { updatedSettings = true; } - if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { - //update signature on the new package setting - //this should always succeed, since we checked the - //signature earlier. - synchronized(mPackages) { - verifySignaturesLP(mSettings.mPackages.get(packageName), pkg, - parseFlags, true); - } - } else { + if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { // Re installation failed. Restore old information // Remove new pkg information if (newPackage != null) { @@ -5781,7 +5762,7 @@ class PackageManagerService extends IPackageManager.Stub { boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); boolean replace = false; - int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE + int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE | (newInstall ? SCAN_NEW_INSTALL : 0); // Result object to be returned res.returnCode = PackageManager.INSTALL_SUCCEEDED; @@ -5911,6 +5892,10 @@ class PackageManagerService extends IPackageManager.Stub { return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); } + private boolean isExternal(PackageParser.Package pkg) { + return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + } + private void extractPublicFiles(PackageParser.Package newPackage, File publicZipFile) throws IOException { final ZipOutputStream publicZipOutStream = @@ -7345,101 +7330,6 @@ class PackageManagerService extends IPackageManager.Stub { } } - /** - * If any of the given 'sigs' is contained in the existing signatures, - * then completely replace the current signatures with the ones in - * 'sigs'. This is used for updating an existing package to a newly - * installed version. - */ - boolean updateSignatures(Signature[] sigs, boolean update) { - if (mSignatures == null) { - if (update) { - assignSignatures(sigs); - } - return true; - } - if (sigs == null) { - return false; - } - - for (int i=0; i<sigs.length; i++) { - Signature sig = sigs[i]; - for (int j=0; j<mSignatures.length; j++) { - if (mSignatures[j].equals(sig)) { - if (update) { - assignSignatures(sigs); - } - return true; - } - } - } - return false; - } - - /** - * If any of the given 'sigs' is contained in the existing signatures, - * then add in any new signatures found in 'sigs'. This is used for - * including a new package into an existing shared user id. - */ - boolean mergeSignatures(Signature[] sigs, boolean update) { - if (mSignatures == null) { - if (update) { - assignSignatures(sigs); - } - return true; - } - if (sigs == null) { - return false; - } - - Signature[] added = null; - int addedCount = 0; - boolean haveMatch = false; - for (int i=0; i<sigs.length; i++) { - Signature sig = sigs[i]; - boolean found = false; - for (int j=0; j<mSignatures.length; j++) { - if (mSignatures[j].equals(sig)) { - found = true; - haveMatch = true; - break; - } - } - - if (!found) { - if (added == null) { - added = new Signature[sigs.length]; - } - added[i] = sig; - addedCount++; - } - } - - if (!haveMatch) { - // Nothing matched -- reject the new signatures. - return false; - } - if (added == null) { - // Completely matched -- nothing else to do. - return true; - } - - // Add additional signatures in. - if (update) { - Signature[] total = new Signature[addedCount+mSignatures.length]; - System.arraycopy(mSignatures, 0, total, 0, mSignatures.length); - int j = mSignatures.length; - for (int i=0; i<added.length; i++) { - if (added[i] != null) { - total[j] = added[i]; - j++; - } - } - mSignatures = total; - } - return true; - } - private void assignSignatures(Signature[] sigs) { if (sigs == null) { mSignatures = null; @@ -8227,6 +8117,15 @@ class PackageManagerService extends IPackageManager.Stub { if (pkg.mVersionCode != p.versionCode) { p.versionCode = pkg.mVersionCode; } + // Update signatures if needed. + if (p.signatures.mSignatures == null) { + p.signatures.assignSignatures(pkg.mSignatures); + } + // If this app defines a shared user id initialize + // the shared user signatures as well. + if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) { + p.sharedUser.signatures.assignSignatures(pkg.mSignatures); + } addPackageSettingLP(p, pkg.packageName, p.sharedUser); } @@ -9655,22 +9554,12 @@ class PackageManagerService extends IPackageManager.Stub { // Parse package int parseFlags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_ON_SDCARD | mDefParseFlags; - PackageParser pp = new PackageParser(codePath); - pp.setSeparateProcesses(mSeparateProcesses); - final PackageParser.Package pkg = pp.parsePackage(new File(codePath), - codePath, mMetrics, parseFlags); - pp = null; doGc = true; - // Check for parse errors - if (pkg == null) { - Slog.e(TAG, "Parse error when installing install pkg : " - + args.cid + " from " + args.cachePath); - continue; - } - setApplicationInfoPaths(pkg, codePath, codePath); synchronized (mInstallLock) { + final PackageParser.Package pkg = scanPackageLI(new File(codePath), + parseFlags, 0); // Scan the package - if (scanPackageLI(pkg, parseFlags, SCAN_MONITOR) != null) { + if (pkg != null) { synchronized (mPackages) { retCode = PackageManager.INSTALL_SUCCEEDED; pkgList.add(pkg.packageName); @@ -9678,8 +9567,8 @@ class PackageManagerService extends IPackageManager.Stub { args.doPostInstall(PackageManager.INSTALL_SUCCEEDED); } } else { - Slog.i(TAG, "Failed to install pkg: " + - pkg.packageName + " from sdcard"); + Slog.i(TAG, "Failed to install pkg from " + + codePath + " from sdcard"); } } |