1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import com.android.server.pm.PackageManagerService.InstallArgs; 20 21 import android.content.pm.PackageManager; 22 import android.util.SparseBooleanArray; 23 24 /** 25 * Tracks the package verification state for a particular package. Each package 26 * verification has a required verifier and zero or more sufficient verifiers. 27 * Only one of the sufficient verifier list must return affirmative to allow the 28 * package to be considered verified. If there are zero sufficient verifiers, 29 * then package verification is considered complete. 30 */ 31 class PackageVerificationState { 32 private final InstallArgs mArgs; 33 34 private final SparseBooleanArray mSufficientVerifierUids; 35 36 private final int mRequiredVerifierUid; 37 38 private boolean mSufficientVerificationComplete; 39 40 private boolean mSufficientVerificationPassed; 41 42 private boolean mRequiredVerificationComplete; 43 44 private boolean mRequiredVerificationPassed; 45 46 /** 47 * Create a new package verification state where {@code requiredVerifierUid} 48 * is the user ID for the package that must reply affirmative before things 49 * can continue. 50 * 51 * @param requiredVerifierUid user ID of required package verifier 52 * @param args 53 */ PackageVerificationState(int requiredVerifierUid, InstallArgs args)54 public PackageVerificationState(int requiredVerifierUid, InstallArgs args) { 55 mRequiredVerifierUid = requiredVerifierUid; 56 mArgs = args; 57 mSufficientVerifierUids = new SparseBooleanArray(); 58 } 59 getInstallArgs()60 public InstallArgs getInstallArgs() { 61 return mArgs; 62 } 63 64 /** 65 * Add a verifier which is added to our sufficient list. 66 * 67 * @param uid user ID of sufficient verifier 68 */ addSufficientVerifier(int uid)69 public void addSufficientVerifier(int uid) { 70 mSufficientVerifierUids.put(uid, true); 71 } 72 73 /** 74 * Should be called when a verification is received from an agent so the 75 * state of the package verification can be tracked. 76 * 77 * @param uid user ID of the verifying agent 78 * @return {@code true} if the verifying agent actually exists in our list 79 */ setVerifierResponse(int uid, int code)80 public boolean setVerifierResponse(int uid, int code) { 81 if (uid == mRequiredVerifierUid) { 82 mRequiredVerificationComplete = true; 83 switch (code) { 84 case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT: 85 mSufficientVerifierUids.clear(); 86 // fall through 87 case PackageManager.VERIFICATION_ALLOW: 88 mRequiredVerificationPassed = true; 89 break; 90 default: 91 mRequiredVerificationPassed = false; 92 } 93 return true; 94 } else { 95 if (mSufficientVerifierUids.get(uid)) { 96 if (code == PackageManager.VERIFICATION_ALLOW) { 97 mSufficientVerificationComplete = true; 98 mSufficientVerificationPassed = true; 99 } 100 101 mSufficientVerifierUids.delete(uid); 102 if (mSufficientVerifierUids.size() == 0) { 103 mSufficientVerificationComplete = true; 104 } 105 106 return true; 107 } 108 } 109 110 return false; 111 } 112 113 /** 114 * Returns whether verification is considered complete. This means that the 115 * required verifier and at least one of the sufficient verifiers has 116 * returned a positive verification. 117 * 118 * @return {@code true} when verification is considered complete 119 */ isVerificationComplete()120 public boolean isVerificationComplete() { 121 if (!mRequiredVerificationComplete) { 122 return false; 123 } 124 125 if (mSufficientVerifierUids.size() == 0) { 126 return true; 127 } 128 129 return mSufficientVerificationComplete; 130 } 131 132 /** 133 * Returns whether installation should be allowed. This should only be 134 * called after {@link #isVerificationComplete()} returns {@code true}. 135 * 136 * @return {@code true} if installation should be allowed 137 */ isInstallAllowed()138 public boolean isInstallAllowed() { 139 if (!mRequiredVerificationPassed) { 140 return false; 141 } 142 143 if (mSufficientVerificationComplete) { 144 return mSufficientVerificationPassed; 145 } 146 147 return true; 148 } 149 } 150