mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
291 lines
13 KiB
Diff
291 lines
13 KiB
Diff
From 55f6ea35d6c238db3c5bdc3a5b0f753567809b45 Mon Sep 17 00:00:00 2001
|
|
From: milaq <micha.laqua@gmail.com>
|
|
Date: Wed, 23 Nov 2016 17:31:23 +0100
|
|
Subject: [PATCH] ignore exchange server policy (1/2)
|
|
|
|
disable policies enforced by an exchange server configuration and the inconveniences and uncertainty that go along with it.
|
|
|
|
based on the "ExchangeBypassXposed" module by Shantanu Goel.
|
|
---
|
|
.../com/android/emailcommon/provider/Policy.java | 34 ++---
|
|
provider_src/com/android/email/SecurityPolicy.java | 163 +--------------------
|
|
.../android/email/EmailNotificationController.java | 10 +-
|
|
3 files changed, 21 insertions(+), 186 deletions(-)
|
|
|
|
diff --git a/emailcommon/src/com/android/emailcommon/provider/Policy.java b/emailcommon/src/com/android/emailcommon/provider/Policy.java
|
|
index f32b750..48acd6f 100755
|
|
--- a/emailcommon/src/com/android/emailcommon/provider/Policy.java
|
|
+++ b/emailcommon/src/com/android/emailcommon/provider/Policy.java
|
|
@@ -226,24 +226,20 @@ public final class Policy extends EmailContent implements EmailContent.PolicyCol
|
|
* zero out complex characters for simple passwords.
|
|
*/
|
|
public void normalize() {
|
|
- if (mPasswordMode == PASSWORD_MODE_NONE) {
|
|
- mPasswordMaxFails = 0;
|
|
- mMaxScreenLockTime = 0;
|
|
- mPasswordMinLength = 0;
|
|
- mPasswordComplexChars = 0;
|
|
- mPasswordHistory = 0;
|
|
- mPasswordExpirationDays = 0;
|
|
- } else {
|
|
- if ((mPasswordMode != PASSWORD_MODE_SIMPLE) &&
|
|
- (mPasswordMode != PASSWORD_MODE_STRONG)) {
|
|
- throw new IllegalArgumentException("password mode");
|
|
- }
|
|
- // If we're only requiring a simple password, set complex chars to zero; note
|
|
- // that EAS can erroneously send non-zero values in this case
|
|
- if (mPasswordMode == PASSWORD_MODE_SIMPLE) {
|
|
- mPasswordComplexChars = 0;
|
|
- }
|
|
- }
|
|
+ mPasswordMode = PASSWORD_MODE_NONE;
|
|
+ mRequireRemoteWipe = false;
|
|
+ mRequireEncryption = false;
|
|
+ mRequireEncryptionExternal = false;
|
|
+ mRequireManualSyncWhenRoaming = false;
|
|
+ mDontAllowCamera = false;
|
|
+ mDontAllowAttachments = false;
|
|
+ mDontAllowHtml = false;
|
|
+ mPasswordMaxFails = 0;
|
|
+ mMaxScreenLockTime = 0;
|
|
+ mPasswordMinLength = 0;
|
|
+ mPasswordComplexChars = 0;
|
|
+ mPasswordHistory = 0;
|
|
+ mPasswordExpirationDays = 0;
|
|
}
|
|
|
|
@Override
|
|
@@ -525,4 +521,4 @@ public final class Policy extends EmailContent implements EmailContent.PolicyCol
|
|
mProtocolPoliciesEnforced = in.readString();
|
|
mProtocolPoliciesUnsupported = in.readString();
|
|
}
|
|
-}
|
|
\ No newline at end of file
|
|
+}
|
|
diff --git a/provider_src/com/android/email/SecurityPolicy.java b/provider_src/com/android/email/SecurityPolicy.java
|
|
index 8418871..f2e7ebd 100644
|
|
--- a/provider_src/com/android/email/SecurityPolicy.java
|
|
+++ b/provider_src/com/android/email/SecurityPolicy.java
|
|
@@ -247,28 +247,7 @@ public class SecurityPolicy {
|
|
* @return true if the requested policies are active, false if not.
|
|
*/
|
|
public boolean isActive(Policy policy) {
|
|
- int reasons = getInactiveReasons(policy);
|
|
- if (DebugUtils.DEBUG && (reasons != 0)) {
|
|
- StringBuilder sb = new StringBuilder("isActive for " + policy + ": ");
|
|
- sb.append("FALSE -> ");
|
|
- if ((reasons & INACTIVE_NEED_ACTIVATION) != 0) {
|
|
- sb.append("no_admin ");
|
|
- }
|
|
- if ((reasons & INACTIVE_NEED_CONFIGURATION) != 0) {
|
|
- sb.append("config ");
|
|
- }
|
|
- if ((reasons & INACTIVE_NEED_PASSWORD) != 0) {
|
|
- sb.append("password ");
|
|
- }
|
|
- if ((reasons & INACTIVE_NEED_ENCRYPTION) != 0) {
|
|
- sb.append("encryption ");
|
|
- }
|
|
- if ((reasons & INACTIVE_PROTOCOL_POLICIES) != 0) {
|
|
- sb.append("protocol ");
|
|
- }
|
|
- LogUtils.d(TAG, sb.toString());
|
|
- }
|
|
- return reasons == 0;
|
|
+ return true;
|
|
}
|
|
|
|
/**
|
|
@@ -317,84 +296,7 @@ public class SecurityPolicy {
|
|
* is needed (typically, by the user) before the required security polices are fully active.
|
|
*/
|
|
public int getInactiveReasons(Policy policy) {
|
|
- // select aggregate set if needed
|
|
- if (policy == null) {
|
|
- policy = getAggregatePolicy();
|
|
- }
|
|
- // quick check for the "empty set" of no policies
|
|
- if (policy == Policy.NO_POLICY) {
|
|
- return 0;
|
|
- }
|
|
- int reasons = 0;
|
|
- DevicePolicyManager dpm = getDPM();
|
|
- if (isActiveAdmin()) {
|
|
- // check each policy explicitly
|
|
- if (policy.mPasswordMinLength > 0) {
|
|
- if (dpm.getPasswordMinimumLength(mAdminName) < policy.mPasswordMinLength) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- }
|
|
- if (policy.mPasswordMode > 0) {
|
|
- if (dpm.getPasswordQuality(mAdminName) < policy.getDPManagerPasswordQuality()) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- if (!dpm.isActivePasswordSufficient()) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- }
|
|
- if (policy.mMaxScreenLockTime > 0) {
|
|
- // Note, we use seconds, dpm uses milliseconds
|
|
- if (dpm.getMaximumTimeToLock(mAdminName) > policy.mMaxScreenLockTime * 1000) {
|
|
- reasons |= INACTIVE_NEED_CONFIGURATION;
|
|
- }
|
|
- }
|
|
- if (policy.mPasswordExpirationDays > 0) {
|
|
- // confirm that expirations are currently set
|
|
- long currentTimeout = dpm.getPasswordExpirationTimeout(mAdminName);
|
|
- if (currentTimeout == 0
|
|
- || currentTimeout > policy.getDPManagerPasswordExpirationTimeout()) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- // confirm that the current password hasn't expired
|
|
- long expirationDate = dpm.getPasswordExpiration(mAdminName);
|
|
- long timeUntilExpiration = expirationDate - System.currentTimeMillis();
|
|
- boolean expired = timeUntilExpiration < 0;
|
|
- if (expired) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- }
|
|
- if (policy.mPasswordHistory > 0) {
|
|
- if (dpm.getPasswordHistoryLength(mAdminName) < policy.mPasswordHistory) {
|
|
- // There's no user action for changes here; this is just a configuration change
|
|
- reasons |= INACTIVE_NEED_CONFIGURATION;
|
|
- }
|
|
- }
|
|
- if (policy.mPasswordComplexChars > 0) {
|
|
- if (dpm.getPasswordMinimumNonLetter(mAdminName) < policy.mPasswordComplexChars) {
|
|
- reasons |= INACTIVE_NEED_PASSWORD;
|
|
- }
|
|
- }
|
|
- if (policy.mRequireEncryption) {
|
|
- int encryptionStatus = getDPM().getStorageEncryptionStatus();
|
|
- if (encryptionStatus != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) {
|
|
- reasons |= INACTIVE_NEED_ENCRYPTION;
|
|
- }
|
|
- }
|
|
- if (policy.mDontAllowCamera && !dpm.getCameraDisabled(mAdminName)) {
|
|
- reasons |= INACTIVE_NEED_CONFIGURATION;
|
|
- }
|
|
- // password failures are counted locally - no test required here
|
|
- // no check required for remote wipe (it's supported, if we're the admin)
|
|
-
|
|
- if (policy.mProtocolPoliciesUnsupported != null) {
|
|
- reasons |= INACTIVE_PROTOCOL_POLICIES;
|
|
- }
|
|
-
|
|
- // If we made it all the way, reasons == 0 here. Otherwise it's a list of grievances.
|
|
- return reasons;
|
|
- }
|
|
- // return false, not active
|
|
- return INACTIVE_NEED_ACTIVATION;
|
|
+ return 0;
|
|
}
|
|
|
|
/**
|
|
@@ -403,53 +305,7 @@ public class SecurityPolicy {
|
|
* we only proceed if we are already active as an admin.
|
|
*/
|
|
public void setActivePolicies() {
|
|
- DevicePolicyManager dpm = getDPM();
|
|
- // compute aggregate set of policies
|
|
- Policy aggregatePolicy = getAggregatePolicy();
|
|
- // if empty set, detach from policy manager
|
|
- if (aggregatePolicy == Policy.NO_POLICY) {
|
|
- if (DebugUtils.DEBUG) {
|
|
- LogUtils.d(TAG, "setActivePolicies: none, remove admin");
|
|
- }
|
|
- dpm.removeActiveAdmin(mAdminName);
|
|
- } else if (isActiveAdmin()) {
|
|
- if (DebugUtils.DEBUG) {
|
|
- LogUtils.d(TAG, "setActivePolicies: " + aggregatePolicy);
|
|
- }
|
|
- // set each policy in the policy manager
|
|
- // password mode & length
|
|
- dpm.setPasswordQuality(mAdminName, aggregatePolicy.getDPManagerPasswordQuality());
|
|
- dpm.setPasswordMinimumLength(mAdminName, aggregatePolicy.mPasswordMinLength);
|
|
- // screen lock time
|
|
- dpm.setMaximumTimeToLock(mAdminName, aggregatePolicy.mMaxScreenLockTime * 1000);
|
|
- // local wipe (failed passwords limit)
|
|
- dpm.setMaximumFailedPasswordsForWipe(mAdminName, aggregatePolicy.mPasswordMaxFails);
|
|
- // password expiration (days until a password expires). API takes mSec.
|
|
- dpm.setPasswordExpirationTimeout(mAdminName,
|
|
- aggregatePolicy.getDPManagerPasswordExpirationTimeout());
|
|
- // password history length (number of previous passwords that may not be reused)
|
|
- dpm.setPasswordHistoryLength(mAdminName, aggregatePolicy.mPasswordHistory);
|
|
- // password minimum complex characters.
|
|
- // Note, in Exchange, "complex chars" simply means "non alpha", but in the DPM,
|
|
- // setting the quality to complex also defaults min symbols=1 and min numeric=1.
|
|
- // We always / safely clear minSymbols & minNumeric to zero (there is no policy
|
|
- // configuration in which we explicitly require a minimum number of digits or symbols.)
|
|
- dpm.setPasswordMinimumSymbols(mAdminName, 0);
|
|
- dpm.setPasswordMinimumNumeric(mAdminName, 0);
|
|
- dpm.setPasswordMinimumNonLetter(mAdminName, aggregatePolicy.mPasswordComplexChars);
|
|
- // Device capabilities
|
|
- try {
|
|
- // If we are running in a managed policy, it is a securityException to even
|
|
- // call setCameraDisabled(), if is disabled is false. We have to swallow
|
|
- // the exception here.
|
|
- dpm.setCameraDisabled(mAdminName, aggregatePolicy.mDontAllowCamera);
|
|
- } catch (SecurityException e) {
|
|
- LogUtils.d(TAG, "SecurityException in setCameraDisabled, nothing changed");
|
|
- }
|
|
-
|
|
- // encryption required
|
|
- dpm.setStorageEncryption(mAdminName, aggregatePolicy.mRequireEncryption);
|
|
- }
|
|
+ return;
|
|
}
|
|
|
|
/**
|
|
@@ -677,12 +533,7 @@ public class SecurityPolicy {
|
|
* return to the caller if there is an unexpected failure. The wipe includes external storage.
|
|
*/
|
|
public void remoteWipe() {
|
|
- DevicePolicyManager dpm = getDPM();
|
|
- if (dpm.isAdminActive(mAdminName)) {
|
|
- dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
|
|
- } else {
|
|
- LogUtils.d(Logging.LOG_TAG, "Could not remote wipe because not device admin.");
|
|
- }
|
|
+ return;
|
|
}
|
|
/**
|
|
* If we are not the active device admin, try to become so.
|
|
@@ -694,11 +545,7 @@ public class SecurityPolicy {
|
|
* @return true if we are already active, false if we are not
|
|
*/
|
|
public boolean isActiveAdmin() {
|
|
- DevicePolicyManager dpm = getDPM();
|
|
- return dpm.isAdminActive(mAdminName)
|
|
- && dpm.hasGrantedPolicy(mAdminName, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
|
|
- && dpm.hasGrantedPolicy(mAdminName, DeviceAdminInfo.USES_ENCRYPTED_STORAGE)
|
|
- && dpm.hasGrantedPolicy(mAdminName, DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
|
|
+ return true;
|
|
}
|
|
|
|
/**
|
|
diff --git a/src/com/android/email/EmailNotificationController.java b/src/com/android/email/EmailNotificationController.java
|
|
index 2d22776..d5b3c02 100644
|
|
--- a/src/com/android/email/EmailNotificationController.java
|
|
+++ b/src/com/android/email/EmailNotificationController.java
|
|
@@ -516,15 +516,7 @@ public class EmailNotificationController implements NotificationController {
|
|
*/
|
|
@Override
|
|
public void showSecurityChangedNotification(Account account) {
|
|
- final Intent intent = new Intent(Intent.ACTION_VIEW,
|
|
- EmailProvider.getIncomingSettingsUri(account.getId()));
|
|
- final String accountName = account.getDisplayName();
|
|
- final String ticker =
|
|
- mContext.getString(R.string.security_changed_ticker_fmt, accountName);
|
|
- final String title =
|
|
- mContext.getString(R.string.security_notification_content_change_title);
|
|
- showNotification(account.mId, ticker, title, accountName, intent,
|
|
- (int)(NOTIFICATION_ID_BASE_SECURITY_CHANGED + account.mId));
|
|
+ return;
|
|
}
|
|
|
|
/**
|
|
--
|
|
2.10.2
|
|
|