DevicePolicyManagerService.java revision 0469f41010d8001dba5e09606bb631b1d3313021
1/* 2 * Copyright (C) 2010 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 17package com.android.server; 18 19import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; 20 21import com.android.internal.R; 22import com.android.internal.os.storage.ExternalStorageFormatter; 23import com.android.internal.util.FastXmlSerializer; 24import com.android.internal.util.JournaledFile; 25import com.android.internal.util.XmlUtils; 26import com.android.internal.widget.LockPatternUtils; 27import com.android.org.conscrypt.TrustedCertificateStore; 28 29import org.xmlpull.v1.XmlPullParser; 30import org.xmlpull.v1.XmlPullParserException; 31import org.xmlpull.v1.XmlSerializer; 32 33import android.app.Activity; 34import android.app.ActivityManagerNative; 35import android.app.AlarmManager; 36import android.app.AppGlobals; 37import android.app.INotificationManager; 38import android.app.Notification; 39import android.app.NotificationManager; 40import android.app.PendingIntent; 41import android.app.admin.DeviceAdminInfo; 42import android.app.admin.DeviceAdminReceiver; 43import android.app.admin.DevicePolicyManager; 44import android.app.admin.IDevicePolicyManager; 45import android.content.BroadcastReceiver; 46import android.content.ComponentName; 47import android.content.ContentResolver; 48import android.content.Context; 49import android.content.Intent; 50import android.content.IntentFilter; 51import android.content.pm.ApplicationInfo; 52import android.content.pm.IPackageManager; 53import android.content.pm.PackageInfo; 54import android.content.pm.PackageManager; 55import android.content.pm.Signature; 56import android.content.pm.PackageManager.NameNotFoundException; 57import android.content.pm.ResolveInfo; 58import android.content.pm.UserInfo; 59import android.net.Uri; 60import android.os.AsyncTask; 61import android.os.Binder; 62import android.os.Bundle; 63import android.os.Environment; 64import android.os.Handler; 65import android.os.IBinder; 66import android.os.IPowerManager; 67import android.os.PowerManager; 68import android.os.Process; 69import android.os.RecoverySystem; 70import android.os.RemoteCallback; 71import android.os.RemoteException; 72import android.os.ServiceManager; 73import android.os.SystemClock; 74import android.os.SystemProperties; 75import android.os.UserHandle; 76import android.os.UserManager; 77import android.provider.Settings; 78import android.security.Credentials; 79import android.security.IKeyChainService; 80import android.security.KeyChain; 81import android.security.KeyChain.KeyChainConnection; 82import android.util.AtomicFile; 83import android.util.Log; 84import android.util.PrintWriterPrinter; 85import android.util.Printer; 86import android.util.Slog; 87import android.util.SparseArray; 88import android.util.Xml; 89import android.view.IWindowManager; 90import android.view.WindowManagerPolicy; 91 92import java.io.ByteArrayInputStream; 93import java.io.File; 94import java.io.FileDescriptor; 95import java.io.FileInputStream; 96import java.io.FileNotFoundException; 97import java.io.FileOutputStream; 98import java.io.IOException; 99import java.io.PrintWriter; 100import java.security.KeyStore.TrustedCertificateEntry; 101import java.security.cert.CertificateException; 102import java.security.cert.CertificateFactory; 103import java.security.cert.X509Certificate; 104import java.text.DateFormat; 105import java.util.ArrayList; 106import java.util.Arrays; 107import java.util.Collection; 108import java.util.Date; 109import java.util.HashMap; 110import java.util.List; 111import java.util.Set; 112 113/** 114 * Implementation of the device policy APIs. 115 */ 116public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 117 118 private static final String TAG = "DevicePolicyManagerService"; 119 120 private static final String DEVICE_POLICIES_XML = "device_policies.xml"; 121 122 private static final int REQUEST_EXPIRE_PASSWORD = 5571; 123 124 private static final long MS_PER_DAY = 86400 * 1000; 125 126 private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms 127 128 protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION 129 = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION"; 130 131 private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning; 132 133 private static final boolean DBG = false; 134 135 final Context mContext; 136 final PowerManager.WakeLock mWakeLock; 137 138 IPowerManager mIPowerManager; 139 IWindowManager mIWindowManager; 140 NotificationManager mNotificationManager; 141 142 private DeviceOwner mDeviceOwner; 143 144 public static class DevicePolicyData { 145 int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 146 int mActivePasswordLength = 0; 147 int mActivePasswordUpperCase = 0; 148 int mActivePasswordLowerCase = 0; 149 int mActivePasswordLetters = 0; 150 int mActivePasswordNumeric = 0; 151 int mActivePasswordSymbols = 0; 152 int mActivePasswordNonLetter = 0; 153 int mFailedPasswordAttempts = 0; 154 155 int mUserHandle;; 156 int mPasswordOwner = -1; 157 long mLastMaximumTimeToLock = -1; 158 159 final HashMap<ComponentName, ActiveAdmin> mAdminMap 160 = new HashMap<ComponentName, ActiveAdmin>(); 161 final ArrayList<ActiveAdmin> mAdminList 162 = new ArrayList<ActiveAdmin>(); 163 164 public DevicePolicyData(int userHandle) { 165 mUserHandle = userHandle; 166 } 167 } 168 169 final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>(); 170 171 Handler mHandler = new Handler(); 172 173 BroadcastReceiver mReceiver = new BroadcastReceiver() { 174 @Override 175 public void onReceive(Context context, Intent intent) { 176 final String action = intent.getAction(); 177 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 178 getSendingUserId()); 179 if (Intent.ACTION_BOOT_COMPLETED.equals(action) 180 || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) { 181 if (DBG) Slog.v(TAG, "Sending password expiration notifications for action " 182 + action + " for user " + userHandle); 183 mHandler.post(new Runnable() { 184 public void run() { 185 handlePasswordExpirationNotification(getUserData(userHandle)); 186 } 187 }); 188 } 189 if (Intent.ACTION_BOOT_COMPLETED.equals(action) 190 || KeyChain.ACTION_STORAGE_CHANGED.equals(action)) { 191 manageMonitoringCertificateNotification(intent); 192 } 193 if (Intent.ACTION_USER_REMOVED.equals(action)) { 194 removeUserData(userHandle); 195 } else if (Intent.ACTION_USER_STARTED.equals(action) 196 || Intent.ACTION_PACKAGE_CHANGED.equals(action) 197 || Intent.ACTION_PACKAGE_REMOVED.equals(action) 198 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 199 200 if (Intent.ACTION_USER_STARTED.equals(action)) { 201 // Reset the policy data 202 synchronized (DevicePolicyManagerService.this) { 203 mUserData.remove(userHandle); 204 } 205 } 206 207 handlePackagesChanged(userHandle); 208 } 209 } 210 }; 211 212 static class ActiveAdmin { 213 final DeviceAdminInfo info; 214 215 int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 216 217 static final int DEF_MINIMUM_PASSWORD_LENGTH = 0; 218 int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH; 219 220 static final int DEF_PASSWORD_HISTORY_LENGTH = 0; 221 int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH; 222 223 static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0; 224 int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE; 225 226 static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0; 227 int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE; 228 229 static final int DEF_MINIMUM_PASSWORD_LETTERS = 1; 230 int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS; 231 232 static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1; 233 int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC; 234 235 static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1; 236 int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS; 237 238 static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0; 239 int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER; 240 241 static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0; 242 long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK; 243 244 static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0; 245 int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE; 246 247 static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0; 248 long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT; 249 250 static final long DEF_PASSWORD_EXPIRATION_DATE = 0; 251 long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE; 252 253 static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none 254 int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED; 255 256 boolean encryptionRequested = false; 257 boolean disableCamera = false; 258 259 // TODO: review implementation decisions with frameworks team 260 boolean specifiesGlobalProxy = false; 261 String globalProxySpec = null; 262 String globalProxyExclusionList = null; 263 264 ActiveAdmin(DeviceAdminInfo _info) { 265 info = _info; 266 } 267 268 int getUid() { return info.getActivityInfo().applicationInfo.uid; } 269 270 public UserHandle getUserHandle() { 271 return new UserHandle(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid)); 272 } 273 274 void writeToXml(XmlSerializer out) 275 throws IllegalArgumentException, IllegalStateException, IOException { 276 out.startTag(null, "policies"); 277 info.writePoliciesToXml(out); 278 out.endTag(null, "policies"); 279 if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 280 out.startTag(null, "password-quality"); 281 out.attribute(null, "value", Integer.toString(passwordQuality)); 282 out.endTag(null, "password-quality"); 283 if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) { 284 out.startTag(null, "min-password-length"); 285 out.attribute(null, "value", Integer.toString(minimumPasswordLength)); 286 out.endTag(null, "min-password-length"); 287 } 288 if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { 289 out.startTag(null, "password-history-length"); 290 out.attribute(null, "value", Integer.toString(passwordHistoryLength)); 291 out.endTag(null, "password-history-length"); 292 } 293 if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) { 294 out.startTag(null, "min-password-uppercase"); 295 out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase)); 296 out.endTag(null, "min-password-uppercase"); 297 } 298 if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) { 299 out.startTag(null, "min-password-lowercase"); 300 out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase)); 301 out.endTag(null, "min-password-lowercase"); 302 } 303 if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) { 304 out.startTag(null, "min-password-letters"); 305 out.attribute(null, "value", Integer.toString(minimumPasswordLetters)); 306 out.endTag(null, "min-password-letters"); 307 } 308 if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) { 309 out.startTag(null, "min-password-numeric"); 310 out.attribute(null, "value", Integer.toString(minimumPasswordNumeric)); 311 out.endTag(null, "min-password-numeric"); 312 } 313 if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) { 314 out.startTag(null, "min-password-symbols"); 315 out.attribute(null, "value", Integer.toString(minimumPasswordSymbols)); 316 out.endTag(null, "min-password-symbols"); 317 } 318 if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) { 319 out.startTag(null, "min-password-nonletter"); 320 out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter)); 321 out.endTag(null, "min-password-nonletter"); 322 } 323 } 324 if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) { 325 out.startTag(null, "max-time-to-unlock"); 326 out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); 327 out.endTag(null, "max-time-to-unlock"); 328 } 329 if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { 330 out.startTag(null, "max-failed-password-wipe"); 331 out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); 332 out.endTag(null, "max-failed-password-wipe"); 333 } 334 if (specifiesGlobalProxy) { 335 out.startTag(null, "specifies-global-proxy"); 336 out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy)); 337 out.endTag(null, "specifies_global_proxy"); 338 if (globalProxySpec != null) { 339 out.startTag(null, "global-proxy-spec"); 340 out.attribute(null, "value", globalProxySpec); 341 out.endTag(null, "global-proxy-spec"); 342 } 343 if (globalProxyExclusionList != null) { 344 out.startTag(null, "global-proxy-exclusion-list"); 345 out.attribute(null, "value", globalProxyExclusionList); 346 out.endTag(null, "global-proxy-exclusion-list"); 347 } 348 } 349 if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) { 350 out.startTag(null, "password-expiration-timeout"); 351 out.attribute(null, "value", Long.toString(passwordExpirationTimeout)); 352 out.endTag(null, "password-expiration-timeout"); 353 } 354 if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) { 355 out.startTag(null, "password-expiration-date"); 356 out.attribute(null, "value", Long.toString(passwordExpirationDate)); 357 out.endTag(null, "password-expiration-date"); 358 } 359 if (encryptionRequested) { 360 out.startTag(null, "encryption-requested"); 361 out.attribute(null, "value", Boolean.toString(encryptionRequested)); 362 out.endTag(null, "encryption-requested"); 363 } 364 if (disableCamera) { 365 out.startTag(null, "disable-camera"); 366 out.attribute(null, "value", Boolean.toString(disableCamera)); 367 out.endTag(null, "disable-camera"); 368 } 369 if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) { 370 out.startTag(null, "disable-keyguard-features"); 371 out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures)); 372 out.endTag(null, "disable-keyguard-features"); 373 } 374 } 375 376 void readFromXml(XmlPullParser parser) 377 throws XmlPullParserException, IOException { 378 int outerDepth = parser.getDepth(); 379 int type; 380 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 381 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 382 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 383 continue; 384 } 385 String tag = parser.getName(); 386 if ("policies".equals(tag)) { 387 info.readPoliciesFromXml(parser); 388 } else if ("password-quality".equals(tag)) { 389 passwordQuality = Integer.parseInt( 390 parser.getAttributeValue(null, "value")); 391 } else if ("min-password-length".equals(tag)) { 392 minimumPasswordLength = Integer.parseInt( 393 parser.getAttributeValue(null, "value")); 394 } else if ("password-history-length".equals(tag)) { 395 passwordHistoryLength = Integer.parseInt( 396 parser.getAttributeValue(null, "value")); 397 } else if ("min-password-uppercase".equals(tag)) { 398 minimumPasswordUpperCase = Integer.parseInt( 399 parser.getAttributeValue(null, "value")); 400 } else if ("min-password-lowercase".equals(tag)) { 401 minimumPasswordLowerCase = Integer.parseInt( 402 parser.getAttributeValue(null, "value")); 403 } else if ("min-password-letters".equals(tag)) { 404 minimumPasswordLetters = Integer.parseInt( 405 parser.getAttributeValue(null, "value")); 406 } else if ("min-password-numeric".equals(tag)) { 407 minimumPasswordNumeric = Integer.parseInt( 408 parser.getAttributeValue(null, "value")); 409 } else if ("min-password-symbols".equals(tag)) { 410 minimumPasswordSymbols = Integer.parseInt( 411 parser.getAttributeValue(null, "value")); 412 } else if ("min-password-nonletter".equals(tag)) { 413 minimumPasswordNonLetter = Integer.parseInt( 414 parser.getAttributeValue(null, "value")); 415 } else if ("max-time-to-unlock".equals(tag)) { 416 maximumTimeToUnlock = Long.parseLong( 417 parser.getAttributeValue(null, "value")); 418 } else if ("max-failed-password-wipe".equals(tag)) { 419 maximumFailedPasswordsForWipe = Integer.parseInt( 420 parser.getAttributeValue(null, "value")); 421 } else if ("specifies-global-proxy".equals(tag)) { 422 specifiesGlobalProxy = Boolean.parseBoolean( 423 parser.getAttributeValue(null, "value")); 424 } else if ("global-proxy-spec".equals(tag)) { 425 globalProxySpec = 426 parser.getAttributeValue(null, "value"); 427 } else if ("global-proxy-exclusion-list".equals(tag)) { 428 globalProxyExclusionList = 429 parser.getAttributeValue(null, "value"); 430 } else if ("password-expiration-timeout".equals(tag)) { 431 passwordExpirationTimeout = Long.parseLong( 432 parser.getAttributeValue(null, "value")); 433 } else if ("password-expiration-date".equals(tag)) { 434 passwordExpirationDate = Long.parseLong( 435 parser.getAttributeValue(null, "value")); 436 } else if ("encryption-requested".equals(tag)) { 437 encryptionRequested = Boolean.parseBoolean( 438 parser.getAttributeValue(null, "value")); 439 } else if ("disable-camera".equals(tag)) { 440 disableCamera = Boolean.parseBoolean( 441 parser.getAttributeValue(null, "value")); 442 } else if ("disable-keyguard-features".equals(tag)) { 443 disabledKeyguardFeatures = Integer.parseInt( 444 parser.getAttributeValue(null, "value")); 445 } else { 446 Slog.w(TAG, "Unknown admin tag: " + tag); 447 } 448 XmlUtils.skipCurrentTag(parser); 449 } 450 } 451 452 void dump(String prefix, PrintWriter pw) { 453 pw.print(prefix); pw.print("uid="); pw.println(getUid()); 454 pw.print(prefix); pw.println("policies:"); 455 ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies(); 456 if (pols != null) { 457 for (int i=0; i<pols.size(); i++) { 458 pw.print(prefix); pw.print(" "); pw.println(pols.get(i).tag); 459 } 460 } 461 pw.print(prefix); pw.print("passwordQuality=0x"); 462 pw.println(Integer.toHexString(passwordQuality)); 463 pw.print(prefix); pw.print("minimumPasswordLength="); 464 pw.println(minimumPasswordLength); 465 pw.print(prefix); pw.print("passwordHistoryLength="); 466 pw.println(passwordHistoryLength); 467 pw.print(prefix); pw.print("minimumPasswordUpperCase="); 468 pw.println(minimumPasswordUpperCase); 469 pw.print(prefix); pw.print("minimumPasswordLowerCase="); 470 pw.println(minimumPasswordLowerCase); 471 pw.print(prefix); pw.print("minimumPasswordLetters="); 472 pw.println(minimumPasswordLetters); 473 pw.print(prefix); pw.print("minimumPasswordNumeric="); 474 pw.println(minimumPasswordNumeric); 475 pw.print(prefix); pw.print("minimumPasswordSymbols="); 476 pw.println(minimumPasswordSymbols); 477 pw.print(prefix); pw.print("minimumPasswordNonLetter="); 478 pw.println(minimumPasswordNonLetter); 479 pw.print(prefix); pw.print("maximumTimeToUnlock="); 480 pw.println(maximumTimeToUnlock); 481 pw.print(prefix); pw.print("maximumFailedPasswordsForWipe="); 482 pw.println(maximumFailedPasswordsForWipe); 483 pw.print(prefix); pw.print("specifiesGlobalProxy="); 484 pw.println(specifiesGlobalProxy); 485 pw.print(prefix); pw.print("passwordExpirationTimeout="); 486 pw.println(passwordExpirationTimeout); 487 pw.print(prefix); pw.print("passwordExpirationDate="); 488 pw.println(passwordExpirationDate); 489 if (globalProxySpec != null) { 490 pw.print(prefix); pw.print("globalProxySpec="); 491 pw.println(globalProxySpec); 492 } 493 if (globalProxyExclusionList != null) { 494 pw.print(prefix); pw.print("globalProxyEclusionList="); 495 pw.println(globalProxyExclusionList); 496 } 497 pw.print(prefix); pw.print("encryptionRequested="); 498 pw.println(encryptionRequested); 499 pw.print(prefix); pw.print("disableCamera="); 500 pw.println(disableCamera); 501 pw.print(prefix); pw.print("disabledKeyguardFeatures="); 502 pw.println(disabledKeyguardFeatures); 503 } 504 } 505 506 private void handlePackagesChanged(int userHandle) { 507 boolean removed = false; 508 if (DBG) Slog.d(TAG, "Handling package changes for user " + userHandle); 509 DevicePolicyData policy = getUserData(userHandle); 510 IPackageManager pm = AppGlobals.getPackageManager(); 511 for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { 512 ActiveAdmin aa = policy.mAdminList.get(i); 513 try { 514 if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null 515 || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) { 516 removed = true; 517 policy.mAdminList.remove(i); 518 } 519 } catch (RemoteException re) { 520 // Shouldn't happen 521 } 522 } 523 if (removed) { 524 validatePasswordOwnerLocked(policy); 525 syncDeviceCapabilitiesLocked(policy); 526 saveSettingsLocked(policy.mUserHandle); 527 } 528 } 529 530 /** 531 * Instantiates the service. 532 */ 533 public DevicePolicyManagerService(Context context) { 534 mContext = context; 535 mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)) 536 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM"); 537 IntentFilter filter = new IntentFilter(); 538 filter.addAction(Intent.ACTION_BOOT_COMPLETED); 539 filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION); 540 filter.addAction(Intent.ACTION_USER_REMOVED); 541 filter.addAction(Intent.ACTION_USER_STARTED); 542 filter.addAction(KeyChain.ACTION_STORAGE_CHANGED); 543 context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); 544 filter = new IntentFilter(); 545 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 546 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 547 filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 548 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 549 filter.addDataScheme("package"); 550 context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); 551 } 552 553 /** 554 * Creates and loads the policy data from xml. 555 * @param userHandle the user for whom to load the policy data 556 * @return 557 */ 558 DevicePolicyData getUserData(int userHandle) { 559 synchronized (this) { 560 DevicePolicyData policy = mUserData.get(userHandle); 561 if (policy == null) { 562 policy = new DevicePolicyData(userHandle); 563 mUserData.append(userHandle, policy); 564 loadSettingsLocked(policy, userHandle); 565 } 566 return policy; 567 } 568 } 569 570 void removeUserData(int userHandle) { 571 synchronized (this) { 572 if (userHandle == UserHandle.USER_OWNER) { 573 Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring."); 574 return; 575 } 576 DevicePolicyData policy = mUserData.get(userHandle); 577 if (policy != null) { 578 mUserData.remove(userHandle); 579 } 580 File policyFile = new File(Environment.getUserSystemDirectory(userHandle), 581 DEVICE_POLICIES_XML); 582 policyFile.delete(); 583 Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath()); 584 } 585 } 586 587 void loadDeviceOwner() { 588 synchronized (this) { 589 if (DeviceOwner.isRegistered()) { 590 mDeviceOwner = new DeviceOwner(); 591 } 592 } 593 } 594 595 /** 596 * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration 597 * reminders. Clears alarm if no expirations are configured. 598 */ 599 protected void setExpirationAlarmCheckLocked(Context context, DevicePolicyData policy) { 600 final long expiration = getPasswordExpirationLocked(null, policy.mUserHandle); 601 final long now = System.currentTimeMillis(); 602 final long timeToExpire = expiration - now; 603 final long alarmTime; 604 if (expiration == 0) { 605 // No expirations are currently configured: Cancel alarm. 606 alarmTime = 0; 607 } else if (timeToExpire <= 0) { 608 // The password has already expired: Repeat every 24 hours. 609 alarmTime = now + MS_PER_DAY; 610 } else { 611 // Selecting the next alarm time: Roll forward to the next 24 hour multiple before 612 // the expiration time. 613 long alarmInterval = timeToExpire % MS_PER_DAY; 614 if (alarmInterval == 0) { 615 alarmInterval = MS_PER_DAY; 616 } 617 alarmTime = now + alarmInterval; 618 } 619 620 long token = Binder.clearCallingIdentity(); 621 try { 622 AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 623 PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD, 624 new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION), 625 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT, 626 new UserHandle(policy.mUserHandle)); 627 am.cancel(pi); 628 if (alarmTime != 0) { 629 am.set(AlarmManager.RTC, alarmTime, pi); 630 } 631 } finally { 632 Binder.restoreCallingIdentity(token); 633 } 634 } 635 636 private IPowerManager getIPowerManager() { 637 if (mIPowerManager == null) { 638 IBinder b = ServiceManager.getService(Context.POWER_SERVICE); 639 mIPowerManager = IPowerManager.Stub.asInterface(b); 640 } 641 return mIPowerManager; 642 } 643 644 private IWindowManager getWindowManager() { 645 if (mIWindowManager == null) { 646 IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE); 647 mIWindowManager = IWindowManager.Stub.asInterface(b); 648 } 649 return mIWindowManager; 650 } 651 652 private NotificationManager getNotificationManager() { 653 if (mNotificationManager == null) { 654 mNotificationManager = 655 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 656 } 657 return mNotificationManager; 658 } 659 660 ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) { 661 ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who); 662 if (admin != null 663 && who.getPackageName().equals(admin.info.getActivityInfo().packageName) 664 && who.getClassName().equals(admin.info.getActivityInfo().name)) { 665 return admin; 666 } 667 return null; 668 } 669 670 ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) 671 throws SecurityException { 672 final int callingUid = Binder.getCallingUid(); 673 final int userHandle = UserHandle.getUserId(callingUid); 674 final DevicePolicyData policy = getUserData(userHandle); 675 if (who != null) { 676 ActiveAdmin admin = policy.mAdminMap.get(who); 677 if (admin == null) { 678 throw new SecurityException("No active admin " + who); 679 } 680 if (admin.getUid() != callingUid) { 681 throw new SecurityException("Admin " + who + " is not owned by uid " 682 + Binder.getCallingUid()); 683 } 684 if (!admin.info.usesPolicy(reqPolicy)) { 685 throw new SecurityException("Admin " + admin.info.getComponent() 686 + " did not specify uses-policy for: " 687 + admin.info.getTagForPolicy(reqPolicy)); 688 } 689 return admin; 690 } else { 691 final int N = policy.mAdminList.size(); 692 for (int i=0; i<N; i++) { 693 ActiveAdmin admin = policy.mAdminList.get(i); 694 if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) { 695 return admin; 696 } 697 } 698 throw new SecurityException("No active admin owned by uid " 699 + Binder.getCallingUid() + " for policy #" + reqPolicy); 700 } 701 } 702 703 void sendAdminCommandLocked(ActiveAdmin admin, String action) { 704 sendAdminCommandLocked(admin, action, null); 705 } 706 707 void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) { 708 Intent intent = new Intent(action); 709 intent.setComponent(admin.info.getComponent()); 710 if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) { 711 intent.putExtra("expiration", admin.passwordExpirationDate); 712 } 713 if (result != null) { 714 mContext.sendOrderedBroadcastAsUser(intent, admin.getUserHandle(), 715 null, result, mHandler, Activity.RESULT_OK, null, null); 716 } else { 717 mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); 718 } 719 } 720 721 void sendAdminCommandLocked(String action, int reqPolicy, int userHandle) { 722 final DevicePolicyData policy = getUserData(userHandle); 723 final int count = policy.mAdminList.size(); 724 if (count > 0) { 725 for (int i = 0; i < count; i++) { 726 ActiveAdmin admin = policy.mAdminList.get(i); 727 if (admin.info.usesPolicy(reqPolicy)) { 728 sendAdminCommandLocked(admin, action); 729 } 730 } 731 } 732 } 733 734 void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) { 735 final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); 736 if (admin != null) { 737 sendAdminCommandLocked(admin, 738 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED, 739 new BroadcastReceiver() { 740 @Override 741 public void onReceive(Context context, Intent intent) { 742 synchronized (DevicePolicyManagerService.this) { 743 int userHandle = admin.getUserHandle().getIdentifier(); 744 DevicePolicyData policy = getUserData(userHandle); 745 boolean doProxyCleanup = admin.info.usesPolicy( 746 DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY); 747 policy.mAdminList.remove(admin); 748 policy.mAdminMap.remove(adminReceiver); 749 validatePasswordOwnerLocked(policy); 750 syncDeviceCapabilitiesLocked(policy); 751 if (doProxyCleanup) { 752 resetGlobalProxyLocked(getUserData(userHandle)); 753 } 754 saveSettingsLocked(userHandle); 755 updateMaximumTimeToLockLocked(policy); 756 } 757 } 758 }); 759 } 760 } 761 762 public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) { 763 enforceCrossUserPermission(userHandle); 764 Intent resolveIntent = new Intent(); 765 resolveIntent.setComponent(adminName); 766 List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers( 767 resolveIntent, 768 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, 769 userHandle); 770 if (infos == null || infos.size() <= 0) { 771 throw new IllegalArgumentException("Unknown admin: " + adminName); 772 } 773 774 try { 775 return new DeviceAdminInfo(mContext, infos.get(0)); 776 } catch (XmlPullParserException e) { 777 Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); 778 return null; 779 } catch (IOException e) { 780 Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); 781 return null; 782 } 783 } 784 785 private static JournaledFile makeJournaledFile(int userHandle) { 786 final String base = userHandle == 0 787 ? "/data/system/" + DEVICE_POLICIES_XML 788 : new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML) 789 .getAbsolutePath(); 790 return new JournaledFile(new File(base), new File(base + ".tmp")); 791 } 792 793 private void saveSettingsLocked(int userHandle) { 794 DevicePolicyData policy = getUserData(userHandle); 795 JournaledFile journal = makeJournaledFile(userHandle); 796 FileOutputStream stream = null; 797 try { 798 stream = new FileOutputStream(journal.chooseForWrite(), false); 799 XmlSerializer out = new FastXmlSerializer(); 800 out.setOutput(stream, "utf-8"); 801 out.startDocument(null, true); 802 803 out.startTag(null, "policies"); 804 805 final int N = policy.mAdminList.size(); 806 for (int i=0; i<N; i++) { 807 ActiveAdmin ap = policy.mAdminList.get(i); 808 if (ap != null) { 809 out.startTag(null, "admin"); 810 out.attribute(null, "name", ap.info.getComponent().flattenToString()); 811 ap.writeToXml(out); 812 out.endTag(null, "admin"); 813 } 814 } 815 816 if (policy.mPasswordOwner >= 0) { 817 out.startTag(null, "password-owner"); 818 out.attribute(null, "value", Integer.toString(policy.mPasswordOwner)); 819 out.endTag(null, "password-owner"); 820 } 821 822 if (policy.mFailedPasswordAttempts != 0) { 823 out.startTag(null, "failed-password-attempts"); 824 out.attribute(null, "value", Integer.toString(policy.mFailedPasswordAttempts)); 825 out.endTag(null, "failed-password-attempts"); 826 } 827 828 if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0 829 || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0 830 || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0 831 || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) { 832 out.startTag(null, "active-password"); 833 out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality)); 834 out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength)); 835 out.attribute(null, "uppercase", Integer.toString(policy.mActivePasswordUpperCase)); 836 out.attribute(null, "lowercase", Integer.toString(policy.mActivePasswordLowerCase)); 837 out.attribute(null, "letters", Integer.toString(policy.mActivePasswordLetters)); 838 out.attribute(null, "numeric", Integer 839 .toString(policy.mActivePasswordNumeric)); 840 out.attribute(null, "symbols", Integer.toString(policy.mActivePasswordSymbols)); 841 out.attribute(null, "nonletter", Integer.toString(policy.mActivePasswordNonLetter)); 842 out.endTag(null, "active-password"); 843 } 844 845 out.endTag(null, "policies"); 846 847 out.endDocument(); 848 stream.close(); 849 journal.commit(); 850 sendChangedNotification(userHandle); 851 } catch (IOException e) { 852 try { 853 if (stream != null) { 854 stream.close(); 855 } 856 } catch (IOException ex) { 857 // Ignore 858 } 859 journal.rollback(); 860 } 861 } 862 863 private void sendChangedNotification(int userHandle) { 864 Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 865 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 866 long ident = Binder.clearCallingIdentity(); 867 try { 868 mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle)); 869 } finally { 870 Binder.restoreCallingIdentity(ident); 871 } 872 } 873 874 private void loadSettingsLocked(DevicePolicyData policy, int userHandle) { 875 JournaledFile journal = makeJournaledFile(userHandle); 876 FileInputStream stream = null; 877 File file = journal.chooseForRead(); 878 try { 879 stream = new FileInputStream(file); 880 XmlPullParser parser = Xml.newPullParser(); 881 parser.setInput(stream, null); 882 883 int type; 884 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 885 && type != XmlPullParser.START_TAG) { 886 } 887 String tag = parser.getName(); 888 if (!"policies".equals(tag)) { 889 throw new XmlPullParserException( 890 "Settings do not start with policies tag: found " + tag); 891 } 892 type = parser.next(); 893 int outerDepth = parser.getDepth(); 894 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 895 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 896 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 897 continue; 898 } 899 tag = parser.getName(); 900 if ("admin".equals(tag)) { 901 String name = parser.getAttributeValue(null, "name"); 902 try { 903 DeviceAdminInfo dai = findAdmin( 904 ComponentName.unflattenFromString(name), userHandle); 905 if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid) 906 != userHandle)) { 907 Slog.w(TAG, "findAdmin returned an incorrect uid " 908 + dai.getActivityInfo().applicationInfo.uid + " for user " 909 + userHandle); 910 } 911 if (dai != null) { 912 ActiveAdmin ap = new ActiveAdmin(dai); 913 ap.readFromXml(parser); 914 policy.mAdminMap.put(ap.info.getComponent(), ap); 915 policy.mAdminList.add(ap); 916 } 917 } catch (RuntimeException e) { 918 Slog.w(TAG, "Failed loading admin " + name, e); 919 } 920 } else if ("failed-password-attempts".equals(tag)) { 921 policy.mFailedPasswordAttempts = Integer.parseInt( 922 parser.getAttributeValue(null, "value")); 923 XmlUtils.skipCurrentTag(parser); 924 } else if ("password-owner".equals(tag)) { 925 policy.mPasswordOwner = Integer.parseInt( 926 parser.getAttributeValue(null, "value")); 927 XmlUtils.skipCurrentTag(parser); 928 } else if ("active-password".equals(tag)) { 929 policy.mActivePasswordQuality = Integer.parseInt( 930 parser.getAttributeValue(null, "quality")); 931 policy.mActivePasswordLength = Integer.parseInt( 932 parser.getAttributeValue(null, "length")); 933 policy.mActivePasswordUpperCase = Integer.parseInt( 934 parser.getAttributeValue(null, "uppercase")); 935 policy.mActivePasswordLowerCase = Integer.parseInt( 936 parser.getAttributeValue(null, "lowercase")); 937 policy.mActivePasswordLetters = Integer.parseInt( 938 parser.getAttributeValue(null, "letters")); 939 policy.mActivePasswordNumeric = Integer.parseInt( 940 parser.getAttributeValue(null, "numeric")); 941 policy.mActivePasswordSymbols = Integer.parseInt( 942 parser.getAttributeValue(null, "symbols")); 943 policy.mActivePasswordNonLetter = Integer.parseInt( 944 parser.getAttributeValue(null, "nonletter")); 945 XmlUtils.skipCurrentTag(parser); 946 } else { 947 Slog.w(TAG, "Unknown tag: " + tag); 948 XmlUtils.skipCurrentTag(parser); 949 } 950 } 951 } catch (NullPointerException e) { 952 Slog.w(TAG, "failed parsing " + file + " " + e); 953 } catch (NumberFormatException e) { 954 Slog.w(TAG, "failed parsing " + file + " " + e); 955 } catch (XmlPullParserException e) { 956 Slog.w(TAG, "failed parsing " + file + " " + e); 957 } catch (FileNotFoundException e) { 958 // Don't be noisy, this is normal if we haven't defined any policies. 959 } catch (IOException e) { 960 Slog.w(TAG, "failed parsing " + file + " " + e); 961 } catch (IndexOutOfBoundsException e) { 962 Slog.w(TAG, "failed parsing " + file + " " + e); 963 } 964 try { 965 if (stream != null) { 966 stream.close(); 967 } 968 } catch (IOException e) { 969 // Ignore 970 } 971 972 // Validate that what we stored for the password quality matches 973 // sufficiently what is currently set. Note that this is only 974 // a sanity check in case the two get out of sync; this should 975 // never normally happen. 976 LockPatternUtils utils = new LockPatternUtils(mContext); 977 if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) { 978 Slog.w(TAG, "Active password quality 0x" 979 + Integer.toHexString(policy.mActivePasswordQuality) 980 + " does not match actual quality 0x" 981 + Integer.toHexString(utils.getActivePasswordQuality())); 982 policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 983 policy.mActivePasswordLength = 0; 984 policy.mActivePasswordUpperCase = 0; 985 policy.mActivePasswordLowerCase = 0; 986 policy.mActivePasswordLetters = 0; 987 policy.mActivePasswordNumeric = 0; 988 policy.mActivePasswordSymbols = 0; 989 policy.mActivePasswordNonLetter = 0; 990 } 991 992 validatePasswordOwnerLocked(policy); 993 syncDeviceCapabilitiesLocked(policy); 994 updateMaximumTimeToLockLocked(policy); 995 } 996 997 static void validateQualityConstant(int quality) { 998 switch (quality) { 999 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 1000 case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK: 1001 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 1002 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 1003 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 1004 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 1005 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 1006 return; 1007 } 1008 throw new IllegalArgumentException("Invalid quality constant: 0x" 1009 + Integer.toHexString(quality)); 1010 } 1011 1012 void validatePasswordOwnerLocked(DevicePolicyData policy) { 1013 if (policy.mPasswordOwner >= 0) { 1014 boolean haveOwner = false; 1015 for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { 1016 if (policy.mAdminList.get(i).getUid() == policy.mPasswordOwner) { 1017 haveOwner = true; 1018 break; 1019 } 1020 } 1021 if (!haveOwner) { 1022 Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner 1023 + " no longer active; disabling"); 1024 policy.mPasswordOwner = -1; 1025 } 1026 } 1027 } 1028 1029 /** 1030 * Pushes down policy information to the system for any policies related to general device 1031 * capabilities that need to be enforced by lower level services (e.g. Camera services). 1032 */ 1033 void syncDeviceCapabilitiesLocked(DevicePolicyData policy) { 1034 // Ensure the status of the camera is synced down to the system. Interested native services 1035 // should monitor this value and act accordingly. 1036 boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false); 1037 boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle); 1038 if (cameraDisabled != systemState) { 1039 long token = Binder.clearCallingIdentity(); 1040 try { 1041 String value = cameraDisabled ? "1" : "0"; 1042 if (DBG) Slog.v(TAG, "Change in camera state [" 1043 + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value); 1044 SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value); 1045 } finally { 1046 Binder.restoreCallingIdentity(token); 1047 } 1048 } 1049 } 1050 1051 public void systemReady() { 1052 synchronized (this) { 1053 loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER); 1054 loadDeviceOwner(); 1055 } 1056 } 1057 1058 private void handlePasswordExpirationNotification(DevicePolicyData policy) { 1059 synchronized (this) { 1060 final long now = System.currentTimeMillis(); 1061 final int N = policy.mAdminList.size(); 1062 if (N <= 0) { 1063 return; 1064 } 1065 for (int i=0; i < N; i++) { 1066 ActiveAdmin admin = policy.mAdminList.get(i); 1067 if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD) 1068 && admin.passwordExpirationTimeout > 0L 1069 && admin.passwordExpirationDate > 0L 1070 && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) { 1071 sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING); 1072 } 1073 } 1074 setExpirationAlarmCheckLocked(mContext, policy); 1075 } 1076 } 1077 1078 private void manageMonitoringCertificateNotification(Intent intent) { 1079 final NotificationManager notificationManager = getNotificationManager(); 1080 1081 final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled(); 1082 if (! hasCert) { 1083 if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) { 1084 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1085 for (UserInfo user : um.getUsers()) { 1086 notificationManager.cancelAsUser( 1087 null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle()); 1088 } 1089 } 1090 return; 1091 } 1092 final boolean isManaged = getDeviceOwner() != null; 1093 int smallIconId; 1094 String contentText; 1095 if (isManaged) { 1096 contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed, 1097 getDeviceOwnerName()); 1098 smallIconId = R.drawable.stat_sys_certificate_info; 1099 } else { 1100 contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown); 1101 smallIconId = android.R.drawable.stat_sys_warning; 1102 } 1103 1104 Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO); 1105 dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 1106 dialogIntent.setPackage("com.android.settings"); 1107 // Notification will be sent individually to all users. The activity should start as 1108 // whichever user is current when it starts. 1109 PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent, 1110 PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT); 1111 1112 Notification noti = new Notification.Builder(mContext) 1113 .setSmallIcon(smallIconId) 1114 .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning)) 1115 .setContentText(contentText) 1116 .setContentIntent(notifyIntent) 1117 .setPriority(Notification.PRIORITY_HIGH) 1118 .setShowWhen(false) 1119 .build(); 1120 1121 // If this is a boot intent, this will fire for each user. But if this is a storage changed 1122 // intent, it will fire once, so we need to notify all users. 1123 if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) { 1124 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1125 for (UserInfo user : um.getUsers()) { 1126 notificationManager.notifyAsUser( 1127 null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle()); 1128 } 1129 } else { 1130 notificationManager.notifyAsUser( 1131 null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT); 1132 } 1133 } 1134 1135 /** 1136 * @param adminReceiver The admin to add 1137 * @param refreshing true = update an active admin, no error 1138 */ 1139 public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) { 1140 mContext.enforceCallingOrSelfPermission( 1141 android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); 1142 enforceCrossUserPermission(userHandle); 1143 1144 DevicePolicyData policy = getUserData(userHandle); 1145 DeviceAdminInfo info = findAdmin(adminReceiver, userHandle); 1146 if (info == null) { 1147 throw new IllegalArgumentException("Bad admin: " + adminReceiver); 1148 } 1149 synchronized (this) { 1150 long ident = Binder.clearCallingIdentity(); 1151 try { 1152 if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { 1153 throw new IllegalArgumentException("Admin is already added"); 1154 } 1155 ActiveAdmin newAdmin = new ActiveAdmin(info); 1156 policy.mAdminMap.put(adminReceiver, newAdmin); 1157 int replaceIndex = -1; 1158 if (refreshing) { 1159 final int N = policy.mAdminList.size(); 1160 for (int i=0; i < N; i++) { 1161 ActiveAdmin oldAdmin = policy.mAdminList.get(i); 1162 if (oldAdmin.info.getComponent().equals(adminReceiver)) { 1163 replaceIndex = i; 1164 break; 1165 } 1166 } 1167 } 1168 if (replaceIndex == -1) { 1169 policy.mAdminList.add(newAdmin); 1170 enableIfNecessary(info.getPackageName(), userHandle); 1171 } else { 1172 policy.mAdminList.set(replaceIndex, newAdmin); 1173 } 1174 saveSettingsLocked(userHandle); 1175 sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED); 1176 } finally { 1177 Binder.restoreCallingIdentity(ident); 1178 } 1179 } 1180 } 1181 1182 public boolean isAdminActive(ComponentName adminReceiver, int userHandle) { 1183 enforceCrossUserPermission(userHandle); 1184 synchronized (this) { 1185 return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null; 1186 } 1187 } 1188 1189 public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId, int userHandle) { 1190 enforceCrossUserPermission(userHandle); 1191 synchronized (this) { 1192 ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle); 1193 if (administrator == null) { 1194 throw new SecurityException("No active admin " + adminReceiver); 1195 } 1196 return administrator.info.usesPolicy(policyId); 1197 } 1198 } 1199 1200 public List<ComponentName> getActiveAdmins(int userHandle) { 1201 enforceCrossUserPermission(userHandle); 1202 synchronized (this) { 1203 DevicePolicyData policy = getUserData(userHandle); 1204 final int N = policy.mAdminList.size(); 1205 if (N <= 0) { 1206 return null; 1207 } 1208 ArrayList<ComponentName> res = new ArrayList<ComponentName>(N); 1209 for (int i=0; i<N; i++) { 1210 res.add(policy.mAdminList.get(i).info.getComponent()); 1211 } 1212 return res; 1213 } 1214 } 1215 1216 public boolean packageHasActiveAdmins(String packageName, int userHandle) { 1217 enforceCrossUserPermission(userHandle); 1218 synchronized (this) { 1219 DevicePolicyData policy = getUserData(userHandle); 1220 final int N = policy.mAdminList.size(); 1221 for (int i=0; i<N; i++) { 1222 if (policy.mAdminList.get(i).info.getPackageName().equals(packageName)) { 1223 return true; 1224 } 1225 } 1226 return false; 1227 } 1228 } 1229 1230 public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) { 1231 enforceCrossUserPermission(userHandle); 1232 synchronized (this) { 1233 ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); 1234 if (admin == null) { 1235 return; 1236 } 1237 if (admin.getUid() != Binder.getCallingUid()) { 1238 // If trying to remove device owner, refuse when the caller is not the owner. 1239 if (mDeviceOwner != null 1240 && adminReceiver.getPackageName().equals(mDeviceOwner.getPackageName())) { 1241 return; 1242 } 1243 mContext.enforceCallingOrSelfPermission( 1244 android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); 1245 } 1246 long ident = Binder.clearCallingIdentity(); 1247 try { 1248 removeActiveAdminLocked(adminReceiver, userHandle); 1249 } finally { 1250 Binder.restoreCallingIdentity(ident); 1251 } 1252 } 1253 } 1254 1255 public void setPasswordQuality(ComponentName who, int quality, int userHandle) { 1256 validateQualityConstant(quality); 1257 enforceCrossUserPermission(userHandle); 1258 1259 synchronized (this) { 1260 if (who == null) { 1261 throw new NullPointerException("ComponentName is null"); 1262 } 1263 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1264 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1265 if (ap.passwordQuality != quality) { 1266 ap.passwordQuality = quality; 1267 saveSettingsLocked(userHandle); 1268 } 1269 } 1270 } 1271 1272 public int getPasswordQuality(ComponentName who, int userHandle) { 1273 enforceCrossUserPermission(userHandle); 1274 synchronized (this) { 1275 int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 1276 DevicePolicyData policy = getUserData(userHandle); 1277 1278 if (who != null) { 1279 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1280 return admin != null ? admin.passwordQuality : mode; 1281 } 1282 1283 final int N = policy.mAdminList.size(); 1284 for (int i=0; i<N; i++) { 1285 ActiveAdmin admin = policy.mAdminList.get(i); 1286 if (mode < admin.passwordQuality) { 1287 mode = admin.passwordQuality; 1288 } 1289 } 1290 return mode; 1291 } 1292 } 1293 1294 public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) { 1295 enforceCrossUserPermission(userHandle); 1296 synchronized (this) { 1297 if (who == null) { 1298 throw new NullPointerException("ComponentName is null"); 1299 } 1300 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1301 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1302 if (ap.minimumPasswordLength != length) { 1303 ap.minimumPasswordLength = length; 1304 saveSettingsLocked(userHandle); 1305 } 1306 } 1307 } 1308 1309 public int getPasswordMinimumLength(ComponentName who, int userHandle) { 1310 enforceCrossUserPermission(userHandle); 1311 synchronized (this) { 1312 DevicePolicyData policy = getUserData(userHandle); 1313 int length = 0; 1314 1315 if (who != null) { 1316 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1317 return admin != null ? admin.minimumPasswordLength : length; 1318 } 1319 1320 final int N = policy.mAdminList.size(); 1321 for (int i=0; i<N; i++) { 1322 ActiveAdmin admin = policy.mAdminList.get(i); 1323 if (length < admin.minimumPasswordLength) { 1324 length = admin.minimumPasswordLength; 1325 } 1326 } 1327 return length; 1328 } 1329 } 1330 1331 public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) { 1332 enforceCrossUserPermission(userHandle); 1333 synchronized (this) { 1334 if (who == null) { 1335 throw new NullPointerException("ComponentName is null"); 1336 } 1337 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1338 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1339 if (ap.passwordHistoryLength != length) { 1340 ap.passwordHistoryLength = length; 1341 saveSettingsLocked(userHandle); 1342 } 1343 } 1344 } 1345 1346 public int getPasswordHistoryLength(ComponentName who, int userHandle) { 1347 enforceCrossUserPermission(userHandle); 1348 synchronized (this) { 1349 DevicePolicyData policy = getUserData(userHandle); 1350 int length = 0; 1351 1352 if (who != null) { 1353 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1354 return admin != null ? admin.passwordHistoryLength : length; 1355 } 1356 1357 final int N = policy.mAdminList.size(); 1358 for (int i = 0; i < N; i++) { 1359 ActiveAdmin admin = policy.mAdminList.get(i); 1360 if (length < admin.passwordHistoryLength) { 1361 length = admin.passwordHistoryLength; 1362 } 1363 } 1364 return length; 1365 } 1366 } 1367 1368 public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) { 1369 enforceCrossUserPermission(userHandle); 1370 synchronized (this) { 1371 if (who == null) { 1372 throw new NullPointerException("ComponentName is null"); 1373 } 1374 if (timeout < 0) { 1375 throw new IllegalArgumentException("Timeout must be >= 0 ms"); 1376 } 1377 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1378 DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD); 1379 // Calling this API automatically bumps the expiration date 1380 final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L; 1381 ap.passwordExpirationDate = expiration; 1382 ap.passwordExpirationTimeout = timeout; 1383 if (timeout > 0L) { 1384 Slog.w(TAG, "setPasswordExpiration(): password will expire on " 1385 + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT) 1386 .format(new Date(expiration))); 1387 } 1388 saveSettingsLocked(userHandle); 1389 // in case this is the first one 1390 setExpirationAlarmCheckLocked(mContext, getUserData(userHandle)); 1391 } 1392 } 1393 1394 /** 1395 * Return a single admin's expiration cycle time, or the min of all cycle times. 1396 * Returns 0 if not configured. 1397 */ 1398 public long getPasswordExpirationTimeout(ComponentName who, int userHandle) { 1399 enforceCrossUserPermission(userHandle); 1400 synchronized (this) { 1401 if (who != null) { 1402 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1403 return admin != null ? admin.passwordExpirationTimeout : 0L; 1404 } 1405 1406 long timeout = 0L; 1407 DevicePolicyData policy = getUserData(userHandle); 1408 final int N = policy.mAdminList.size(); 1409 for (int i = 0; i < N; i++) { 1410 ActiveAdmin admin = policy.mAdminList.get(i); 1411 if (timeout == 0L || (admin.passwordExpirationTimeout != 0L 1412 && timeout > admin.passwordExpirationTimeout)) { 1413 timeout = admin.passwordExpirationTimeout; 1414 } 1415 } 1416 return timeout; 1417 } 1418 } 1419 1420 /** 1421 * Return a single admin's expiration date/time, or the min (soonest) for all admins. 1422 * Returns 0 if not configured. 1423 */ 1424 private long getPasswordExpirationLocked(ComponentName who, int userHandle) { 1425 if (who != null) { 1426 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1427 return admin != null ? admin.passwordExpirationDate : 0L; 1428 } 1429 1430 long timeout = 0L; 1431 DevicePolicyData policy = getUserData(userHandle); 1432 final int N = policy.mAdminList.size(); 1433 for (int i = 0; i < N; i++) { 1434 ActiveAdmin admin = policy.mAdminList.get(i); 1435 if (timeout == 0L || (admin.passwordExpirationDate != 0 1436 && timeout > admin.passwordExpirationDate)) { 1437 timeout = admin.passwordExpirationDate; 1438 } 1439 } 1440 return timeout; 1441 } 1442 1443 public long getPasswordExpiration(ComponentName who, int userHandle) { 1444 enforceCrossUserPermission(userHandle); 1445 synchronized (this) { 1446 return getPasswordExpirationLocked(who, userHandle); 1447 } 1448 } 1449 1450 public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) { 1451 enforceCrossUserPermission(userHandle); 1452 synchronized (this) { 1453 if (who == null) { 1454 throw new NullPointerException("ComponentName is null"); 1455 } 1456 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1457 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1458 if (ap.minimumPasswordUpperCase != length) { 1459 ap.minimumPasswordUpperCase = length; 1460 saveSettingsLocked(userHandle); 1461 } 1462 } 1463 } 1464 1465 public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) { 1466 enforceCrossUserPermission(userHandle); 1467 synchronized (this) { 1468 int length = 0; 1469 1470 if (who != null) { 1471 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1472 return admin != null ? admin.minimumPasswordUpperCase : length; 1473 } 1474 1475 DevicePolicyData policy = getUserData(userHandle); 1476 final int N = policy.mAdminList.size(); 1477 for (int i=0; i<N; i++) { 1478 ActiveAdmin admin = policy.mAdminList.get(i); 1479 if (length < admin.minimumPasswordUpperCase) { 1480 length = admin.minimumPasswordUpperCase; 1481 } 1482 } 1483 return length; 1484 } 1485 } 1486 1487 public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) { 1488 enforceCrossUserPermission(userHandle); 1489 synchronized (this) { 1490 if (who == null) { 1491 throw new NullPointerException("ComponentName is null"); 1492 } 1493 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1494 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1495 if (ap.minimumPasswordLowerCase != length) { 1496 ap.minimumPasswordLowerCase = length; 1497 saveSettingsLocked(userHandle); 1498 } 1499 } 1500 } 1501 1502 public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) { 1503 enforceCrossUserPermission(userHandle); 1504 synchronized (this) { 1505 int length = 0; 1506 1507 if (who != null) { 1508 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1509 return admin != null ? admin.minimumPasswordLowerCase : length; 1510 } 1511 1512 DevicePolicyData policy = getUserData(userHandle); 1513 final int N = policy.mAdminList.size(); 1514 for (int i=0; i<N; i++) { 1515 ActiveAdmin admin = policy.mAdminList.get(i); 1516 if (length < admin.minimumPasswordLowerCase) { 1517 length = admin.minimumPasswordLowerCase; 1518 } 1519 } 1520 return length; 1521 } 1522 } 1523 1524 public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) { 1525 enforceCrossUserPermission(userHandle); 1526 synchronized (this) { 1527 if (who == null) { 1528 throw new NullPointerException("ComponentName is null"); 1529 } 1530 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1531 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1532 if (ap.minimumPasswordLetters != length) { 1533 ap.minimumPasswordLetters = length; 1534 saveSettingsLocked(userHandle); 1535 } 1536 } 1537 } 1538 1539 public int getPasswordMinimumLetters(ComponentName who, int userHandle) { 1540 enforceCrossUserPermission(userHandle); 1541 synchronized (this) { 1542 int length = 0; 1543 1544 if (who != null) { 1545 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1546 return admin != null ? admin.minimumPasswordLetters : length; 1547 } 1548 1549 DevicePolicyData policy = getUserData(userHandle); 1550 final int N = policy.mAdminList.size(); 1551 for (int i=0; i<N; i++) { 1552 ActiveAdmin admin = policy.mAdminList.get(i); 1553 if (length < admin.minimumPasswordLetters) { 1554 length = admin.minimumPasswordLetters; 1555 } 1556 } 1557 return length; 1558 } 1559 } 1560 1561 public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) { 1562 enforceCrossUserPermission(userHandle); 1563 synchronized (this) { 1564 if (who == null) { 1565 throw new NullPointerException("ComponentName is null"); 1566 } 1567 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1568 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1569 if (ap.minimumPasswordNumeric != length) { 1570 ap.minimumPasswordNumeric = length; 1571 saveSettingsLocked(userHandle); 1572 } 1573 } 1574 } 1575 1576 public int getPasswordMinimumNumeric(ComponentName who, int userHandle) { 1577 enforceCrossUserPermission(userHandle); 1578 synchronized (this) { 1579 int length = 0; 1580 1581 if (who != null) { 1582 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1583 return admin != null ? admin.minimumPasswordNumeric : length; 1584 } 1585 1586 DevicePolicyData policy = getUserData(userHandle); 1587 final int N = policy.mAdminList.size(); 1588 for (int i = 0; i < N; i++) { 1589 ActiveAdmin admin = policy.mAdminList.get(i); 1590 if (length < admin.minimumPasswordNumeric) { 1591 length = admin.minimumPasswordNumeric; 1592 } 1593 } 1594 return length; 1595 } 1596 } 1597 1598 public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) { 1599 enforceCrossUserPermission(userHandle); 1600 synchronized (this) { 1601 if (who == null) { 1602 throw new NullPointerException("ComponentName is null"); 1603 } 1604 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1605 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1606 if (ap.minimumPasswordSymbols != length) { 1607 ap.minimumPasswordSymbols = length; 1608 saveSettingsLocked(userHandle); 1609 } 1610 } 1611 } 1612 1613 public int getPasswordMinimumSymbols(ComponentName who, int userHandle) { 1614 enforceCrossUserPermission(userHandle); 1615 synchronized (this) { 1616 int length = 0; 1617 1618 if (who != null) { 1619 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1620 return admin != null ? admin.minimumPasswordSymbols : length; 1621 } 1622 1623 DevicePolicyData policy = getUserData(userHandle); 1624 final int N = policy.mAdminList.size(); 1625 for (int i=0; i<N; i++) { 1626 ActiveAdmin admin = policy.mAdminList.get(i); 1627 if (length < admin.minimumPasswordSymbols) { 1628 length = admin.minimumPasswordSymbols; 1629 } 1630 } 1631 return length; 1632 } 1633 } 1634 1635 public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) { 1636 enforceCrossUserPermission(userHandle); 1637 synchronized (this) { 1638 if (who == null) { 1639 throw new NullPointerException("ComponentName is null"); 1640 } 1641 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1642 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1643 if (ap.minimumPasswordNonLetter != length) { 1644 ap.minimumPasswordNonLetter = length; 1645 saveSettingsLocked(userHandle); 1646 } 1647 } 1648 } 1649 1650 public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) { 1651 enforceCrossUserPermission(userHandle); 1652 synchronized (this) { 1653 int length = 0; 1654 1655 if (who != null) { 1656 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1657 return admin != null ? admin.minimumPasswordNonLetter : length; 1658 } 1659 1660 DevicePolicyData policy = getUserData(userHandle); 1661 final int N = policy.mAdminList.size(); 1662 for (int i=0; i<N; i++) { 1663 ActiveAdmin admin = policy.mAdminList.get(i); 1664 if (length < admin.minimumPasswordNonLetter) { 1665 length = admin.minimumPasswordNonLetter; 1666 } 1667 } 1668 return length; 1669 } 1670 } 1671 1672 public boolean isActivePasswordSufficient(int userHandle) { 1673 enforceCrossUserPermission(userHandle); 1674 synchronized (this) { 1675 DevicePolicyData policy = getUserData(userHandle); 1676 // This API can only be called by an active device admin, 1677 // so try to retrieve it to check that the caller is one. 1678 getActiveAdminForCallerLocked(null, 1679 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1680 if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle) 1681 || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) { 1682 return false; 1683 } 1684 if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1685 return true; 1686 } 1687 return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle) 1688 && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle) 1689 && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle) 1690 && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle) 1691 && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle) 1692 && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle); 1693 } 1694 } 1695 1696 public int getCurrentFailedPasswordAttempts(int userHandle) { 1697 enforceCrossUserPermission(userHandle); 1698 synchronized (this) { 1699 // This API can only be called by an active device admin, 1700 // so try to retrieve it to check that the caller is one. 1701 getActiveAdminForCallerLocked(null, 1702 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1703 return getUserData(userHandle).mFailedPasswordAttempts; 1704 } 1705 } 1706 1707 public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) { 1708 enforceCrossUserPermission(userHandle); 1709 synchronized (this) { 1710 // This API can only be called by an active device admin, 1711 // so try to retrieve it to check that the caller is one. 1712 getActiveAdminForCallerLocked(who, 1713 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 1714 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1715 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1716 if (ap.maximumFailedPasswordsForWipe != num) { 1717 ap.maximumFailedPasswordsForWipe = num; 1718 saveSettingsLocked(userHandle); 1719 } 1720 } 1721 } 1722 1723 public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) { 1724 enforceCrossUserPermission(userHandle); 1725 synchronized (this) { 1726 DevicePolicyData policy = getUserData(userHandle); 1727 int count = 0; 1728 1729 if (who != null) { 1730 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1731 return admin != null ? admin.maximumFailedPasswordsForWipe : count; 1732 } 1733 1734 final int N = policy.mAdminList.size(); 1735 for (int i=0; i<N; i++) { 1736 ActiveAdmin admin = policy.mAdminList.get(i); 1737 if (count == 0) { 1738 count = admin.maximumFailedPasswordsForWipe; 1739 } else if (admin.maximumFailedPasswordsForWipe != 0 1740 && count > admin.maximumFailedPasswordsForWipe) { 1741 count = admin.maximumFailedPasswordsForWipe; 1742 } 1743 } 1744 return count; 1745 } 1746 } 1747 1748 public boolean resetPassword(String password, int flags, int userHandle) { 1749 enforceCrossUserPermission(userHandle); 1750 int quality; 1751 synchronized (this) { 1752 // This API can only be called by an active device admin, 1753 // so try to retrieve it to check that the caller is one. 1754 getActiveAdminForCallerLocked(null, 1755 DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); 1756 quality = getPasswordQuality(null, userHandle); 1757 if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 1758 int realQuality = LockPatternUtils.computePasswordQuality(password); 1759 if (realQuality < quality 1760 && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1761 Slog.w(TAG, "resetPassword: password quality 0x" 1762 + Integer.toHexString(realQuality) 1763 + " does not meet required quality 0x" 1764 + Integer.toHexString(quality)); 1765 return false; 1766 } 1767 quality = Math.max(realQuality, quality); 1768 } 1769 int length = getPasswordMinimumLength(null, userHandle); 1770 if (password.length() < length) { 1771 Slog.w(TAG, "resetPassword: password length " + password.length() 1772 + " does not meet required length " + length); 1773 return false; 1774 } 1775 if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1776 int letters = 0; 1777 int uppercase = 0; 1778 int lowercase = 0; 1779 int numbers = 0; 1780 int symbols = 0; 1781 int nonletter = 0; 1782 for (int i = 0; i < password.length(); i++) { 1783 char c = password.charAt(i); 1784 if (c >= 'A' && c <= 'Z') { 1785 letters++; 1786 uppercase++; 1787 } else if (c >= 'a' && c <= 'z') { 1788 letters++; 1789 lowercase++; 1790 } else if (c >= '0' && c <= '9') { 1791 numbers++; 1792 nonletter++; 1793 } else { 1794 symbols++; 1795 nonletter++; 1796 } 1797 } 1798 int neededLetters = getPasswordMinimumLetters(null, userHandle); 1799 if(letters < neededLetters) { 1800 Slog.w(TAG, "resetPassword: number of letters " + letters 1801 + " does not meet required number of letters " + neededLetters); 1802 return false; 1803 } 1804 int neededNumbers = getPasswordMinimumNumeric(null, userHandle); 1805 if (numbers < neededNumbers) { 1806 Slog.w(TAG, "resetPassword: number of numerical digits " + numbers 1807 + " does not meet required number of numerical digits " 1808 + neededNumbers); 1809 return false; 1810 } 1811 int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle); 1812 if (lowercase < neededLowerCase) { 1813 Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase 1814 + " does not meet required number of lowercase letters " 1815 + neededLowerCase); 1816 return false; 1817 } 1818 int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle); 1819 if (uppercase < neededUpperCase) { 1820 Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase 1821 + " does not meet required number of uppercase letters " 1822 + neededUpperCase); 1823 return false; 1824 } 1825 int neededSymbols = getPasswordMinimumSymbols(null, userHandle); 1826 if (symbols < neededSymbols) { 1827 Slog.w(TAG, "resetPassword: number of special symbols " + symbols 1828 + " does not meet required number of special symbols " + neededSymbols); 1829 return false; 1830 } 1831 int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle); 1832 if (nonletter < neededNonLetter) { 1833 Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter 1834 + " does not meet required number of non-letter characters " 1835 + neededNonLetter); 1836 return false; 1837 } 1838 } 1839 } 1840 1841 int callingUid = Binder.getCallingUid(); 1842 DevicePolicyData policy = getUserData(userHandle); 1843 if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) { 1844 Slog.w(TAG, "resetPassword: already set by another uid and not entered by user"); 1845 return false; 1846 } 1847 1848 // Don't do this with the lock held, because it is going to call 1849 // back in to the service. 1850 long ident = Binder.clearCallingIdentity(); 1851 try { 1852 LockPatternUtils utils = new LockPatternUtils(mContext); 1853 utils.saveLockPassword(password, quality, false, userHandle); 1854 synchronized (this) { 1855 int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) 1856 != 0 ? callingUid : -1; 1857 if (policy.mPasswordOwner != newOwner) { 1858 policy.mPasswordOwner = newOwner; 1859 saveSettingsLocked(userHandle); 1860 } 1861 } 1862 } finally { 1863 Binder.restoreCallingIdentity(ident); 1864 } 1865 1866 return true; 1867 } 1868 1869 public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) { 1870 enforceCrossUserPermission(userHandle); 1871 synchronized (this) { 1872 if (who == null) { 1873 throw new NullPointerException("ComponentName is null"); 1874 } 1875 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1876 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1877 if (ap.maximumTimeToUnlock != timeMs) { 1878 ap.maximumTimeToUnlock = timeMs; 1879 saveSettingsLocked(userHandle); 1880 updateMaximumTimeToLockLocked(getUserData(userHandle)); 1881 } 1882 } 1883 } 1884 1885 void updateMaximumTimeToLockLocked(DevicePolicyData policy) { 1886 long timeMs = getMaximumTimeToLock(null, policy.mUserHandle); 1887 if (policy.mLastMaximumTimeToLock == timeMs) { 1888 return; 1889 } 1890 1891 long ident = Binder.clearCallingIdentity(); 1892 try { 1893 if (timeMs <= 0) { 1894 timeMs = Integer.MAX_VALUE; 1895 } else { 1896 // Make sure KEEP_SCREEN_ON is disabled, since that 1897 // would allow bypassing of the maximum time to lock. 1898 Settings.Global.putInt(mContext.getContentResolver(), 1899 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); 1900 } 1901 1902 policy.mLastMaximumTimeToLock = timeMs; 1903 1904 try { 1905 getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs); 1906 } catch (RemoteException e) { 1907 Slog.w(TAG, "Failure talking with power manager", e); 1908 } 1909 } finally { 1910 Binder.restoreCallingIdentity(ident); 1911 } 1912 } 1913 1914 public long getMaximumTimeToLock(ComponentName who, int userHandle) { 1915 enforceCrossUserPermission(userHandle); 1916 synchronized (this) { 1917 long time = 0; 1918 1919 if (who != null) { 1920 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 1921 return admin != null ? admin.maximumTimeToUnlock : time; 1922 } 1923 1924 DevicePolicyData policy = getUserData(userHandle); 1925 final int N = policy.mAdminList.size(); 1926 for (int i=0; i<N; i++) { 1927 ActiveAdmin admin = policy.mAdminList.get(i); 1928 if (time == 0) { 1929 time = admin.maximumTimeToUnlock; 1930 } else if (admin.maximumTimeToUnlock != 0 1931 && time > admin.maximumTimeToUnlock) { 1932 time = admin.maximumTimeToUnlock; 1933 } 1934 } 1935 return time; 1936 } 1937 } 1938 1939 public void lockNow() { 1940 synchronized (this) { 1941 // This API can only be called by an active device admin, 1942 // so try to retrieve it to check that the caller is one. 1943 getActiveAdminForCallerLocked(null, 1944 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1945 lockNowUnchecked(); 1946 } 1947 } 1948 1949 private void lockNowUnchecked() { 1950 long ident = Binder.clearCallingIdentity(); 1951 try { 1952 // Power off the display 1953 getIPowerManager().goToSleep(SystemClock.uptimeMillis(), 1954 PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN); 1955 // Ensure the device is locked 1956 getWindowManager().lockNow(null); 1957 } catch (RemoteException e) { 1958 } finally { 1959 Binder.restoreCallingIdentity(ident); 1960 } 1961 } 1962 1963 private boolean isExtStorageEncrypted() { 1964 String state = SystemProperties.get("vold.decrypt"); 1965 return !"".equals(state); 1966 } 1967 1968 public boolean installCaCert(byte[] certBuffer) throws RemoteException { 1969 mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null); 1970 KeyChainConnection keyChainConnection = null; 1971 byte[] pemCert; 1972 try { 1973 X509Certificate cert = parseCert(certBuffer); 1974 pemCert = Credentials.convertToPem(cert); 1975 } catch (CertificateException ce) { 1976 Log.e(TAG, "Problem converting cert", ce); 1977 return false; 1978 } catch (IOException ioe) { 1979 Log.e(TAG, "Problem reading cert", ioe); 1980 return false; 1981 } 1982 try { 1983 keyChainConnection = KeyChain.bind(mContext); 1984 try { 1985 keyChainConnection.getService().installCaCertificate(pemCert); 1986 return true; 1987 } finally { 1988 if (keyChainConnection != null) { 1989 keyChainConnection.close(); 1990 keyChainConnection = null; 1991 } 1992 } 1993 } catch (InterruptedException e1) { 1994 Log.w(TAG, "installCaCertsToKeyChain(): ", e1); 1995 Thread.currentThread().interrupt(); 1996 } 1997 return false; 1998 } 1999 2000 private static X509Certificate parseCert(byte[] certBuffer) 2001 throws CertificateException, IOException { 2002 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 2003 return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream( 2004 certBuffer)); 2005 } 2006 2007 public void uninstallCaCert(final byte[] certBuffer) { 2008 mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null); 2009 TrustedCertificateStore certStore = new TrustedCertificateStore(); 2010 String alias = null; 2011 try { 2012 X509Certificate cert = parseCert(certBuffer); 2013 alias = certStore.getCertificateAlias(cert); 2014 } catch (CertificateException ce) { 2015 Log.e(TAG, "Problem creating X509Certificate", ce); 2016 return; 2017 } catch (IOException ioe) { 2018 Log.e(TAG, "Problem reading certificate", ioe); 2019 return; 2020 } 2021 try { 2022 KeyChainConnection keyChainConnection = KeyChain.bind(mContext); 2023 IKeyChainService service = keyChainConnection.getService(); 2024 try { 2025 service.deleteCaCertificate(alias); 2026 } catch (RemoteException e) { 2027 Log.e(TAG, "from CaCertUninstaller: ", e); 2028 } finally { 2029 keyChainConnection.close(); 2030 keyChainConnection = null; 2031 } 2032 } catch (InterruptedException ie) { 2033 Log.w(TAG, "CaCertUninstaller: ", ie); 2034 Thread.currentThread().interrupt(); 2035 } 2036 } 2037 2038 void wipeDataLocked(int flags) { 2039 // If the SD card is encrypted and non-removable, we have to force a wipe. 2040 boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted(); 2041 boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0; 2042 2043 // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated. 2044 if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) { 2045 Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET); 2046 intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true); 2047 intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); 2048 mWakeLock.acquire(10000); 2049 mContext.startService(intent); 2050 } else { 2051 try { 2052 RecoverySystem.rebootWipeUserData(mContext); 2053 } catch (IOException e) { 2054 Slog.w(TAG, "Failed requesting data wipe", e); 2055 } 2056 } 2057 } 2058 2059 public void wipeData(int flags, final int userHandle) { 2060 enforceCrossUserPermission(userHandle); 2061 synchronized (this) { 2062 // This API can only be called by an active device admin, 2063 // so try to retrieve it to check that the caller is one. 2064 getActiveAdminForCallerLocked(null, 2065 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 2066 long ident = Binder.clearCallingIdentity(); 2067 try { 2068 wipeDeviceOrUserLocked(flags, userHandle); 2069 } finally { 2070 Binder.restoreCallingIdentity(ident); 2071 } 2072 } 2073 } 2074 2075 private void wipeDeviceOrUserLocked(int flags, final int userHandle) { 2076 if (userHandle == UserHandle.USER_OWNER) { 2077 wipeDataLocked(flags); 2078 } else { 2079 lockNowUnchecked(); 2080 mHandler.post(new Runnable() { 2081 public void run() { 2082 try { 2083 ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER); 2084 ((UserManager) mContext.getSystemService(Context.USER_SERVICE)) 2085 .removeUser(userHandle); 2086 } catch (RemoteException re) { 2087 // Shouldn't happen 2088 } 2089 } 2090 }); 2091 } 2092 } 2093 2094 public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) { 2095 enforceCrossUserPermission(userHandle); 2096 mContext.enforceCallingOrSelfPermission( 2097 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 2098 2099 synchronized (this) { 2100 ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle); 2101 if (admin == null) { 2102 try { 2103 result.sendResult(null); 2104 } catch (RemoteException e) { 2105 } 2106 return; 2107 } 2108 Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED); 2109 intent.setComponent(admin.info.getComponent()); 2110 mContext.sendOrderedBroadcastAsUser(intent, new UserHandle(userHandle), 2111 null, new BroadcastReceiver() { 2112 @Override 2113 public void onReceive(Context context, Intent intent) { 2114 try { 2115 result.sendResult(getResultExtras(false)); 2116 } catch (RemoteException e) { 2117 } 2118 } 2119 }, null, Activity.RESULT_OK, null, null); 2120 } 2121 } 2122 2123 public void setActivePasswordState(int quality, int length, int letters, int uppercase, 2124 int lowercase, int numbers, int symbols, int nonletter, int userHandle) { 2125 enforceCrossUserPermission(userHandle); 2126 mContext.enforceCallingOrSelfPermission( 2127 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 2128 DevicePolicyData p = getUserData(userHandle); 2129 2130 validateQualityConstant(quality); 2131 2132 synchronized (this) { 2133 if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length 2134 || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters 2135 || p.mActivePasswordUpperCase != uppercase 2136 || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers 2137 || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) { 2138 long ident = Binder.clearCallingIdentity(); 2139 try { 2140 p.mActivePasswordQuality = quality; 2141 p.mActivePasswordLength = length; 2142 p.mActivePasswordLetters = letters; 2143 p.mActivePasswordLowerCase = lowercase; 2144 p.mActivePasswordUpperCase = uppercase; 2145 p.mActivePasswordNumeric = numbers; 2146 p.mActivePasswordSymbols = symbols; 2147 p.mActivePasswordNonLetter = nonletter; 2148 p.mFailedPasswordAttempts = 0; 2149 saveSettingsLocked(userHandle); 2150 updatePasswordExpirationsLocked(userHandle); 2151 setExpirationAlarmCheckLocked(mContext, p); 2152 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, 2153 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle); 2154 } finally { 2155 Binder.restoreCallingIdentity(ident); 2156 } 2157 } 2158 } 2159 } 2160 2161 /** 2162 * Called any time the device password is updated. Resets all password expiration clocks. 2163 */ 2164 private void updatePasswordExpirationsLocked(int userHandle) { 2165 DevicePolicyData policy = getUserData(userHandle); 2166 final int N = policy.mAdminList.size(); 2167 if (N > 0) { 2168 for (int i=0; i<N; i++) { 2169 ActiveAdmin admin = policy.mAdminList.get(i); 2170 if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) { 2171 long timeout = admin.passwordExpirationTimeout; 2172 long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L; 2173 admin.passwordExpirationDate = expiration; 2174 } 2175 } 2176 saveSettingsLocked(userHandle); 2177 } 2178 } 2179 2180 public void reportFailedPasswordAttempt(int userHandle) { 2181 enforceCrossUserPermission(userHandle); 2182 mContext.enforceCallingOrSelfPermission( 2183 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 2184 2185 synchronized (this) { 2186 DevicePolicyData policy = getUserData(userHandle); 2187 long ident = Binder.clearCallingIdentity(); 2188 try { 2189 policy.mFailedPasswordAttempts++; 2190 saveSettingsLocked(userHandle); 2191 int max = getMaximumFailedPasswordsForWipe(null, userHandle); 2192 if (max > 0 && policy.mFailedPasswordAttempts >= max) { 2193 wipeDeviceOrUserLocked(0, userHandle); 2194 } 2195 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED, 2196 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle); 2197 } finally { 2198 Binder.restoreCallingIdentity(ident); 2199 } 2200 } 2201 } 2202 2203 public void reportSuccessfulPasswordAttempt(int userHandle) { 2204 enforceCrossUserPermission(userHandle); 2205 mContext.enforceCallingOrSelfPermission( 2206 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 2207 2208 synchronized (this) { 2209 DevicePolicyData policy = getUserData(userHandle); 2210 if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) { 2211 long ident = Binder.clearCallingIdentity(); 2212 try { 2213 policy.mFailedPasswordAttempts = 0; 2214 policy.mPasswordOwner = -1; 2215 saveSettingsLocked(userHandle); 2216 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED, 2217 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle); 2218 } finally { 2219 Binder.restoreCallingIdentity(ident); 2220 } 2221 } 2222 } 2223 } 2224 2225 public ComponentName setGlobalProxy(ComponentName who, String proxySpec, 2226 String exclusionList, int userHandle) { 2227 enforceCrossUserPermission(userHandle); 2228 synchronized(this) { 2229 if (who == null) { 2230 throw new NullPointerException("ComponentName is null"); 2231 } 2232 2233 // Only check if owner has set global proxy. We don't allow other users to set it. 2234 DevicePolicyData policy = getUserData(UserHandle.USER_OWNER); 2235 ActiveAdmin admin = getActiveAdminForCallerLocked(who, 2236 DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY); 2237 2238 // Scan through active admins and find if anyone has already 2239 // set the global proxy. 2240 Set<ComponentName> compSet = policy.mAdminMap.keySet(); 2241 for (ComponentName component : compSet) { 2242 ActiveAdmin ap = policy.mAdminMap.get(component); 2243 if ((ap.specifiesGlobalProxy) && (!component.equals(who))) { 2244 // Another admin already sets the global proxy 2245 // Return it to the caller. 2246 return component; 2247 } 2248 } 2249 2250 // If the user is not the owner, don't set the global proxy. Fail silently. 2251 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { 2252 Slog.w(TAG, "Only the owner is allowed to set the global proxy. User " 2253 + userHandle + " is not permitted."); 2254 return null; 2255 } 2256 if (proxySpec == null) { 2257 admin.specifiesGlobalProxy = false; 2258 admin.globalProxySpec = null; 2259 admin.globalProxyExclusionList = null; 2260 } else { 2261 2262 admin.specifiesGlobalProxy = true; 2263 admin.globalProxySpec = proxySpec; 2264 admin.globalProxyExclusionList = exclusionList; 2265 } 2266 2267 // Reset the global proxy accordingly 2268 // Do this using system permissions, as apps cannot write to secure settings 2269 long origId = Binder.clearCallingIdentity(); 2270 resetGlobalProxyLocked(policy); 2271 Binder.restoreCallingIdentity(origId); 2272 return null; 2273 } 2274 } 2275 2276 public ComponentName getGlobalProxyAdmin(int userHandle) { 2277 enforceCrossUserPermission(userHandle); 2278 synchronized(this) { 2279 DevicePolicyData policy = getUserData(UserHandle.USER_OWNER); 2280 // Scan through active admins and find if anyone has already 2281 // set the global proxy. 2282 final int N = policy.mAdminList.size(); 2283 for (int i = 0; i < N; i++) { 2284 ActiveAdmin ap = policy.mAdminList.get(i); 2285 if (ap.specifiesGlobalProxy) { 2286 // Device admin sets the global proxy 2287 // Return it to the caller. 2288 return ap.info.getComponent(); 2289 } 2290 } 2291 } 2292 // No device admin sets the global proxy. 2293 return null; 2294 } 2295 2296 private void resetGlobalProxyLocked(DevicePolicyData policy) { 2297 final int N = policy.mAdminList.size(); 2298 for (int i = 0; i < N; i++) { 2299 ActiveAdmin ap = policy.mAdminList.get(i); 2300 if (ap.specifiesGlobalProxy) { 2301 saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList); 2302 return; 2303 } 2304 } 2305 // No device admins defining global proxies - reset global proxy settings to none 2306 saveGlobalProxyLocked(null, null); 2307 } 2308 2309 private void saveGlobalProxyLocked(String proxySpec, String exclusionList) { 2310 if (exclusionList == null) { 2311 exclusionList = ""; 2312 } 2313 if (proxySpec == null) { 2314 proxySpec = ""; 2315 } 2316 // Remove white spaces 2317 proxySpec = proxySpec.trim(); 2318 String data[] = proxySpec.split(":"); 2319 int proxyPort = 8080; 2320 if (data.length > 1) { 2321 try { 2322 proxyPort = Integer.parseInt(data[1]); 2323 } catch (NumberFormatException e) {} 2324 } 2325 exclusionList = exclusionList.trim(); 2326 ContentResolver res = mContext.getContentResolver(); 2327 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]); 2328 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort); 2329 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, 2330 exclusionList); 2331 } 2332 2333 /** 2334 * Set the storage encryption request for a single admin. Returns the new total request 2335 * status (for all admins). 2336 */ 2337 public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) { 2338 enforceCrossUserPermission(userHandle); 2339 synchronized (this) { 2340 // Check for permissions 2341 if (who == null) { 2342 throw new NullPointerException("ComponentName is null"); 2343 } 2344 // Only owner can set storage encryption 2345 if (userHandle != UserHandle.USER_OWNER 2346 || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { 2347 Slog.w(TAG, "Only owner is allowed to set storage encryption. User " 2348 + UserHandle.getCallingUserId() + " is not permitted."); 2349 return 0; 2350 } 2351 2352 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 2353 DeviceAdminInfo.USES_ENCRYPTED_STORAGE); 2354 2355 // Quick exit: If the filesystem does not support encryption, we can exit early. 2356 if (!isEncryptionSupported()) { 2357 return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 2358 } 2359 2360 // (1) Record the value for the admin so it's sticky 2361 if (ap.encryptionRequested != encrypt) { 2362 ap.encryptionRequested = encrypt; 2363 saveSettingsLocked(userHandle); 2364 } 2365 2366 DevicePolicyData policy = getUserData(UserHandle.USER_OWNER); 2367 // (2) Compute "max" for all admins 2368 boolean newRequested = false; 2369 final int N = policy.mAdminList.size(); 2370 for (int i = 0; i < N; i++) { 2371 newRequested |= policy.mAdminList.get(i).encryptionRequested; 2372 } 2373 2374 // Notify OS of new request 2375 setEncryptionRequested(newRequested); 2376 2377 // Return the new global request status 2378 return newRequested 2379 ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE 2380 : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; 2381 } 2382 } 2383 2384 /** 2385 * Get the current storage encryption request status for a given admin, or aggregate of all 2386 * active admins. 2387 */ 2388 public boolean getStorageEncryption(ComponentName who, int userHandle) { 2389 enforceCrossUserPermission(userHandle); 2390 synchronized (this) { 2391 // Check for permissions if a particular caller is specified 2392 if (who != null) { 2393 // When checking for a single caller, status is based on caller's request 2394 ActiveAdmin ap = getActiveAdminUncheckedLocked(who, userHandle); 2395 return ap != null ? ap.encryptionRequested : false; 2396 } 2397 2398 // If no particular caller is specified, return the aggregate set of requests. 2399 // This is short circuited by returning true on the first hit. 2400 DevicePolicyData policy = getUserData(userHandle); 2401 final int N = policy.mAdminList.size(); 2402 for (int i = 0; i < N; i++) { 2403 if (policy.mAdminList.get(i).encryptionRequested) { 2404 return true; 2405 } 2406 } 2407 return false; 2408 } 2409 } 2410 2411 /** 2412 * Get the current encryption status of the device. 2413 */ 2414 public int getStorageEncryptionStatus(int userHandle) { 2415 enforceCrossUserPermission(userHandle); 2416 return getEncryptionStatus(); 2417 } 2418 2419 /** 2420 * Hook to low-levels: This should report if the filesystem supports encrypted storage. 2421 */ 2422 private boolean isEncryptionSupported() { 2423 // Note, this can be implemented as 2424 // return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 2425 // But is provided as a separate internal method if there's a faster way to do a 2426 // simple check for supported-or-not. 2427 return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 2428 } 2429 2430 /** 2431 * Hook to low-levels: Reporting the current status of encryption. 2432 * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or 2433 * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or 2434 * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}. 2435 */ 2436 private int getEncryptionStatus() { 2437 String status = SystemProperties.get("ro.crypto.state", "unsupported"); 2438 if ("encrypted".equalsIgnoreCase(status)) { 2439 return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE; 2440 } else if ("unencrypted".equalsIgnoreCase(status)) { 2441 return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; 2442 } else { 2443 return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 2444 } 2445 } 2446 2447 /** 2448 * Hook to low-levels: If needed, record the new admin setting for encryption. 2449 */ 2450 private void setEncryptionRequested(boolean encrypt) { 2451 } 2452 2453 /** 2454 * The system property used to share the state of the camera. The native camera service 2455 * is expected to read this property and act accordingly. 2456 */ 2457 public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled"; 2458 2459 /** 2460 * Disables all device cameras according to the specified admin. 2461 */ 2462 public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) { 2463 enforceCrossUserPermission(userHandle); 2464 synchronized (this) { 2465 if (who == null) { 2466 throw new NullPointerException("ComponentName is null"); 2467 } 2468 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 2469 DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); 2470 if (ap.disableCamera != disabled) { 2471 ap.disableCamera = disabled; 2472 saveSettingsLocked(userHandle); 2473 } 2474 syncDeviceCapabilitiesLocked(getUserData(userHandle)); 2475 } 2476 } 2477 2478 /** 2479 * Gets whether or not all device cameras are disabled for a given admin, or disabled for any 2480 * active admins. 2481 */ 2482 public boolean getCameraDisabled(ComponentName who, int userHandle) { 2483 synchronized (this) { 2484 if (who != null) { 2485 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 2486 return (admin != null) ? admin.disableCamera : false; 2487 } 2488 2489 DevicePolicyData policy = getUserData(userHandle); 2490 // Determine whether or not the device camera is disabled for any active admins. 2491 final int N = policy.mAdminList.size(); 2492 for (int i = 0; i < N; i++) { 2493 ActiveAdmin admin = policy.mAdminList.get(i); 2494 if (admin.disableCamera) { 2495 return true; 2496 } 2497 } 2498 return false; 2499 } 2500 } 2501 2502 /** 2503 * Selectively disable keyguard features. 2504 */ 2505 public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) { 2506 enforceCrossUserPermission(userHandle); 2507 synchronized (this) { 2508 if (who == null) { 2509 throw new NullPointerException("ComponentName is null"); 2510 } 2511 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 2512 DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); 2513 if (ap.disabledKeyguardFeatures != which) { 2514 ap.disabledKeyguardFeatures = which; 2515 saveSettingsLocked(userHandle); 2516 } 2517 syncDeviceCapabilitiesLocked(getUserData(userHandle)); 2518 } 2519 } 2520 2521 /** 2522 * Gets the disabled state for features in keyguard for the given admin, 2523 * or the aggregate of all active admins if who is null. 2524 */ 2525 public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) { 2526 enforceCrossUserPermission(userHandle); 2527 synchronized (this) { 2528 if (who != null) { 2529 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); 2530 return (admin != null) ? admin.disabledKeyguardFeatures : 0; 2531 } 2532 2533 // Determine which keyguard features are disabled for any active admins. 2534 DevicePolicyData policy = getUserData(userHandle); 2535 final int N = policy.mAdminList.size(); 2536 int which = 0; 2537 for (int i = 0; i < N; i++) { 2538 ActiveAdmin admin = policy.mAdminList.get(i); 2539 which |= admin.disabledKeyguardFeatures; 2540 } 2541 return which; 2542 } 2543 } 2544 2545 @Override 2546 public boolean setDeviceOwner(String packageName, String ownerName) { 2547 if (packageName == null 2548 || !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) { 2549 throw new IllegalArgumentException("Invalid package name " + packageName 2550 + " for device owner"); 2551 } 2552 synchronized (this) { 2553 if (mDeviceOwner == null && !isDeviceProvisioned()) { 2554 mDeviceOwner = new DeviceOwner(packageName, ownerName); 2555 mDeviceOwner.writeOwnerFile(); 2556 return true; 2557 } else { 2558 throw new IllegalStateException("Trying to set device owner to " + packageName 2559 + ", owner=" + mDeviceOwner.getPackageName() 2560 + ", device_provisioned=" + isDeviceProvisioned()); 2561 } 2562 } 2563 } 2564 2565 @Override 2566 public boolean isDeviceOwner(String packageName) { 2567 synchronized (this) { 2568 return mDeviceOwner != null 2569 && mDeviceOwner.getPackageName().equals(packageName); 2570 } 2571 } 2572 2573 @Override 2574 public String getDeviceOwner() { 2575 synchronized (this) { 2576 if (mDeviceOwner != null) { 2577 return mDeviceOwner.getPackageName(); 2578 } 2579 } 2580 return null; 2581 } 2582 2583 @Override 2584 public String getDeviceOwnerName() { 2585 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 2586 synchronized (this) { 2587 if (mDeviceOwner != null) { 2588 return mDeviceOwner.getName(); 2589 } 2590 } 2591 return null; 2592 } 2593 2594 private boolean isDeviceProvisioned() { 2595 return Settings.Global.getInt(mContext.getContentResolver(), 2596 Settings.Global.DEVICE_PROVISIONED, 0) > 0; 2597 } 2598 2599 private void enforceCrossUserPermission(int userHandle) { 2600 if (userHandle < 0) { 2601 throw new IllegalArgumentException("Invalid userId " + userHandle); 2602 } 2603 final int callingUid = Binder.getCallingUid(); 2604 if (userHandle == UserHandle.getUserId(callingUid)) return; 2605 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2606 mContext.enforceCallingOrSelfPermission( 2607 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have" 2608 + " INTERACT_ACROSS_USERS_FULL permission"); 2609 } 2610 } 2611 2612 private void enableIfNecessary(String packageName, int userId) { 2613 try { 2614 IPackageManager ipm = AppGlobals.getPackageManager(); 2615 ApplicationInfo ai = ipm.getApplicationInfo(packageName, 2616 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, 2617 userId); 2618 if (ai.enabledSetting 2619 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { 2620 ipm.setApplicationEnabledSetting(packageName, 2621 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 2622 PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager"); 2623 } 2624 } catch (RemoteException e) { 2625 } 2626 } 2627 2628 @Override 2629 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2630 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2631 != PackageManager.PERMISSION_GRANTED) { 2632 2633 pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid=" 2634 + Binder.getCallingPid() 2635 + ", uid=" + Binder.getCallingUid()); 2636 return; 2637 } 2638 2639 final Printer p = new PrintWriterPrinter(pw); 2640 2641 synchronized (this) { 2642 p.println("Current Device Policy Manager state:"); 2643 2644 int userCount = mUserData.size(); 2645 for (int u = 0; u < userCount; u++) { 2646 DevicePolicyData policy = getUserData(mUserData.keyAt(u)); 2647 p.println(" Enabled Device Admins (User " + policy.mUserHandle + "):"); 2648 final int N = policy.mAdminList.size(); 2649 for (int i=0; i<N; i++) { 2650 ActiveAdmin ap = policy.mAdminList.get(i); 2651 if (ap != null) { 2652 pw.print(" "); pw.print(ap.info.getComponent().flattenToShortString()); 2653 pw.println(":"); 2654 ap.dump(" ", pw); 2655 } 2656 } 2657 2658 pw.println(" "); 2659 pw.print(" mPasswordOwner="); pw.println(policy.mPasswordOwner); 2660 } 2661 } 2662 } 2663 2664 static class DeviceOwner { 2665 private static final String DEVICE_OWNER_XML = "device_owner.xml"; 2666 private static final String TAG_DEVICE_OWNER = "device-owner"; 2667 private static final String ATTR_NAME = "name"; 2668 private static final String ATTR_PACKAGE = "package"; 2669 private String mPackageName; 2670 private String mOwnerName; 2671 2672 DeviceOwner() { 2673 readOwnerFile(); 2674 } 2675 2676 DeviceOwner(String packageName, String ownerName) { 2677 this.mPackageName = packageName; 2678 this.mOwnerName = ownerName; 2679 } 2680 2681 static boolean isRegistered() { 2682 return new File(Environment.getSystemSecureDirectory(), 2683 DEVICE_OWNER_XML).exists(); 2684 } 2685 2686 String getPackageName() { 2687 return mPackageName; 2688 } 2689 2690 String getName() { 2691 return mOwnerName; 2692 } 2693 2694 static boolean isInstalled(String packageName, PackageManager pm) { 2695 try { 2696 PackageInfo pi; 2697 if ((pi = pm.getPackageInfo(packageName, 0)) != null) { 2698 if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 2699 return true; 2700 } 2701 } 2702 } catch (NameNotFoundException nnfe) { 2703 Slog.w(TAG, "Device Owner package " + packageName + " not installed."); 2704 } 2705 return false; 2706 } 2707 2708 void readOwnerFile() { 2709 AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(), 2710 DEVICE_OWNER_XML)); 2711 try { 2712 FileInputStream input = file.openRead(); 2713 XmlPullParser parser = Xml.newPullParser(); 2714 parser.setInput(input, null); 2715 int type; 2716 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 2717 && type != XmlPullParser.START_TAG) { 2718 } 2719 String tag = parser.getName(); 2720 if (!TAG_DEVICE_OWNER.equals(tag)) { 2721 throw new XmlPullParserException( 2722 "Device Owner file does not start with device-owner tag: found " + tag); 2723 } 2724 mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE); 2725 mOwnerName = parser.getAttributeValue(null, ATTR_NAME); 2726 input.close(); 2727 } catch (XmlPullParserException xppe) { 2728 Slog.e(TAG, "Error parsing device-owner file\n" + xppe); 2729 } catch (IOException ioe) { 2730 Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe); 2731 } 2732 } 2733 2734 void writeOwnerFile() { 2735 synchronized (this) { 2736 writeOwnerFileLocked(); 2737 } 2738 } 2739 2740 private void writeOwnerFileLocked() { 2741 AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(), 2742 DEVICE_OWNER_XML)); 2743 try { 2744 FileOutputStream output = file.startWrite(); 2745 XmlSerializer out = new FastXmlSerializer(); 2746 out.setOutput(output, "utf-8"); 2747 out.startDocument(null, true); 2748 out.startTag(null, TAG_DEVICE_OWNER); 2749 out.attribute(null, ATTR_PACKAGE, mPackageName); 2750 if (mOwnerName != null) { 2751 out.attribute(null, ATTR_NAME, mOwnerName); 2752 } 2753 out.endTag(null, TAG_DEVICE_OWNER); 2754 out.endDocument(); 2755 out.flush(); 2756 file.finishWrite(output); 2757 } catch (IOException ioe) { 2758 Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe); 2759 } 2760 } 2761 } 2762} 2763