From 55f6ea35d6c238db3c5bdc3a5b0f753567809b45 Mon Sep 17 00:00:00 2001 From: milaq 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