Merge "CA cert monitoring: add notifications and actions for dialog" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f5aba5ad1e
@ -1372,7 +1372,7 @@ public class DevicePolicyManager {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasAnyCaCertsInstalled() {
|
||||
public static boolean hasAnyCaCertsInstalled() {
|
||||
TrustedCertificateStore certStore = new TrustedCertificateStore();
|
||||
Set<String> aliases = certStore.userAliases();
|
||||
return aliases != null && !aliases.isEmpty();
|
||||
|
@ -159,6 +159,38 @@ public final class Settings {
|
||||
public static final String ACTION_SECURITY_SETTINGS =
|
||||
"android.settings.SECURITY_SETTINGS";
|
||||
|
||||
/**
|
||||
* Activity Action: Show trusted credentials settings, opening to the user tab,
|
||||
* to allow management of installed credentials.
|
||||
* <p>
|
||||
* In some cases, a matching Activity may not exist, so ensure you
|
||||
* safeguard against this.
|
||||
* <p>
|
||||
* Input: Nothing.
|
||||
* <p>
|
||||
* Output: Nothing.
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_TRUSTED_CREDENTIALS_USER =
|
||||
"com.android.settings.TRUSTED_CREDENTIALS_USER";
|
||||
|
||||
/**
|
||||
* Activity Action: Show dialog explaining that an installed CA cert may enable
|
||||
* monitoring of encrypted network traffic.
|
||||
* <p>
|
||||
* In some cases, a matching Activity may not exist, so ensure you
|
||||
* safeguard against this.
|
||||
* <p>
|
||||
* Input: Nothing.
|
||||
* <p>
|
||||
* Output: Nothing.
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_MONITORING_CERT_INFO =
|
||||
"com.android.settings.MONITORING_CERT_INFO";
|
||||
|
||||
/**
|
||||
* Activity Action: Show settings to allow configuration of privacy options.
|
||||
* <p>
|
||||
|
BIN
core/res/res/drawable-hdpi/stat_sys_certificate_info.png
Normal file
BIN
core/res/res/drawable-hdpi/stat_sys_certificate_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
core/res/res/drawable-mdpi/stat_sys_certificate_info.png
Normal file
BIN
core/res/res/drawable-mdpi/stat_sys_certificate_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 930 B |
BIN
core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
Normal file
BIN
core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
Normal file
BIN
core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
@ -273,6 +273,18 @@
|
||||
<!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
|
||||
<string name="low_memory" product="default">Phone storage is full. Delete some files to free space.</string>
|
||||
|
||||
<!-- SSL CA cert notification --> <skip />
|
||||
<!-- Shows up when there is a user SSL CA Cert installed on the
|
||||
device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
|
||||
<string name="ssl_ca_cert_warning">Network may be monitored</string>
|
||||
<!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
|
||||
i.e. "Network may be monitored". This says that an unknown party is doing the monitoring.
|
||||
[CHAR LIMIT=100]-->
|
||||
<string name="ssl_ca_cert_noti_by_unknown">By an unknown third party</string>
|
||||
<!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
|
||||
i.e. "Network may be monitored". This indicates who is doing the monitoring.
|
||||
[CHAR LIMIT=100]-->
|
||||
<string name="ssl_ca_cert_noti_managed">By <xliff:g id="managing_domain">%s</xliff:g></string>
|
||||
|
||||
<!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
|
||||
<string name="me">Me</string>
|
||||
|
@ -886,6 +886,9 @@
|
||||
<java-symbol type="string" name="write_fail_reason_cannot_write" />
|
||||
<java-symbol type="string" name="transient_navigation_confirmation" />
|
||||
<java-symbol type="string" name="transient_navigation_confirmation_long" />
|
||||
<java-symbol type="string" name="ssl_ca_cert_noti_by_unknown" />
|
||||
<java-symbol type="string" name="ssl_ca_cert_noti_managed" />
|
||||
<java-symbol type="string" name="ssl_ca_cert_warning" />
|
||||
|
||||
<java-symbol type="plurals" name="abbrev_in_num_days" />
|
||||
<java-symbol type="plurals" name="abbrev_in_num_hours" />
|
||||
@ -1008,6 +1011,7 @@
|
||||
<java-symbol type="drawable" name="stat_notify_rssi_in_range" />
|
||||
<java-symbol type="drawable" name="stat_sys_gps_on" />
|
||||
<java-symbol type="drawable" name="stat_sys_tether_wifi" />
|
||||
<java-symbol type="drawable" name="stat_sys_certificate_info" />
|
||||
<java-symbol type="drawable" name="status_bar_background" />
|
||||
<java-symbol type="drawable" name="sym_keyboard_shift" />
|
||||
<java-symbol type="drawable" name="sym_keyboard_shift_locked" />
|
||||
|
@ -500,16 +500,5 @@
|
||||
<!-- Shows up when there is a user SSL CA Cert installed on the
|
||||
device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
|
||||
<string name="ssl_ca_cert_warning">Network may be monitored</string>
|
||||
<!-- Button to close the SSL CA cert warning dialog box. [CHAR LIMIT=NONE] -->
|
||||
<string name="done_button">Done</string>
|
||||
<!-- Title of Dialog warning users of SSL monitoring. [CHAR LIMIT=NONE] -->
|
||||
<string name="ssl_ca_cert_dialog_title">Network Monitoring</string>
|
||||
<!-- Text of message to show to users whose administrator has installed a SSL CA Cert.
|
||||
[CHAR LIMIT=NONE] -->
|
||||
<string name="ssl_ca_cert_info_message">This device is managed by: <xliff:g id="managing_domain">%s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity, including emails, apps, and secure websites.\n\nFor more information,contact your administrator.</string>
|
||||
<!-- Text of warning to show to users that have a SSL CA Cert installed. [CHAR LIMIT=NONE] -->
|
||||
<string name="ssl_ca_cert_warning_message">A third party is capable of monitoring your network\nactivity, including emails, apps, and secure websites.\n\nA trusted credential installed on your device is making this possible.</string>
|
||||
<!-- Label on button that will take the user to the Trusted Credentials settings page.
|
||||
[CHAR LIMIT=NONE]-->
|
||||
<string name="ssl_ca_cert_settings_button">Check trusted credentials</string>
|
||||
|
||||
</resources>
|
||||
|
@ -194,7 +194,7 @@ class QuickSettings {
|
||||
mQueryCertTask = new AsyncTask<Void, Void, Pair<Boolean, Boolean>>() {
|
||||
@Override
|
||||
protected Pair<Boolean, Boolean> doInBackground(Void... params) {
|
||||
boolean hasCert = mDevicePolicyManager.hasAnyCaCertsInstalled();
|
||||
boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
|
||||
boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
|
||||
|
||||
return Pair.create(hasCert, isManaged);
|
||||
@ -764,7 +764,7 @@ class QuickSettings {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
collapsePanels();
|
||||
showSslCaCertWarningDialog();
|
||||
startSettingsActivity(Settings.ACTION_MONITORING_CERT_INFO);
|
||||
}
|
||||
});
|
||||
|
||||
@ -832,45 +832,6 @@ class QuickSettings {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void showSslCaCertWarningDialog() {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
builder.setTitle(R.string.ssl_ca_cert_dialog_title);
|
||||
builder.setCancelable(true);
|
||||
final boolean hasDeviceOwner = mDevicePolicyManager.getDeviceOwner() != null;
|
||||
int buttonLabel;
|
||||
if (hasDeviceOwner) {
|
||||
// Institutional case. Show informational message.
|
||||
String message = mContext.getResources().getString(R.string.ssl_ca_cert_info_message,
|
||||
mDevicePolicyManager.getDeviceOwnerName());
|
||||
builder.setMessage(message);
|
||||
buttonLabel = R.string.done_button;
|
||||
} else {
|
||||
// Consumer case. Show scary warning.
|
||||
builder.setMessage(R.string.ssl_ca_cert_warning_message);
|
||||
buttonLabel = R.string.ssl_ca_cert_settings_button;
|
||||
}
|
||||
|
||||
builder.setPositiveButton(buttonLabel, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// do something.
|
||||
if (hasDeviceOwner) {
|
||||
// Close
|
||||
} else {
|
||||
startSettingsActivity("com.android.settings.TRUSTED_CREDENTIALS_USER");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Dialog dialog = builder.create();
|
||||
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void updateWifiDisplayStatus() {
|
||||
mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
|
||||
applyWifiDisplayStatus();
|
||||
|
@ -18,6 +18,7 @@ package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.os.storage.ExternalStorageFormatter;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.util.JournaledFile;
|
||||
@ -33,6 +34,9 @@ import android.app.Activity;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.admin.DeviceAdminInfo;
|
||||
import android.app.admin.DeviceAdminReceiver;
|
||||
@ -51,6 +55,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.Signature;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
@ -123,6 +128,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
|
||||
= "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
|
||||
|
||||
private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning;
|
||||
|
||||
private static final boolean DBG = false;
|
||||
|
||||
final Context mContext;
|
||||
@ -130,6 +137,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
IPowerManager mIPowerManager;
|
||||
IWindowManager mIWindowManager;
|
||||
NotificationManager mNotificationManager;
|
||||
|
||||
private DeviceOwner mDeviceOwner;
|
||||
|
||||
@ -177,7 +185,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
handlePasswordExpirationNotification(getUserData(userHandle));
|
||||
}
|
||||
});
|
||||
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
||||
}
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|
||||
|| KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
|
||||
manageMonitoringCertificateNotification(intent);
|
||||
}
|
||||
if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
||||
removeUserData(userHandle);
|
||||
} else if (Intent.ACTION_USER_STARTED.equals(action)
|
||||
|| Intent.ACTION_PACKAGE_CHANGED.equals(action)
|
||||
@ -526,6 +539,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
|
||||
filter.addAction(Intent.ACTION_USER_REMOVED);
|
||||
filter.addAction(Intent.ACTION_USER_STARTED);
|
||||
filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
|
||||
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
@ -635,6 +649,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
return mIWindowManager;
|
||||
}
|
||||
|
||||
private NotificationManager getNotificationManager() {
|
||||
if (mNotificationManager == null) {
|
||||
mNotificationManager =
|
||||
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
}
|
||||
return mNotificationManager;
|
||||
}
|
||||
|
||||
ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
|
||||
ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
|
||||
if (admin != null
|
||||
@ -1053,6 +1075,63 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void manageMonitoringCertificateNotification(Intent intent) {
|
||||
final NotificationManager notificationManager = getNotificationManager();
|
||||
|
||||
final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
|
||||
if (! hasCert) {
|
||||
if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
|
||||
UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
for (UserInfo user : um.getUsers()) {
|
||||
notificationManager.cancelAsUser(
|
||||
null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
final boolean isManaged = getDeviceOwner() != null;
|
||||
int smallIconId;
|
||||
String contentText;
|
||||
if (isManaged) {
|
||||
contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
|
||||
getDeviceOwnerName());
|
||||
smallIconId = R.drawable.stat_sys_certificate_info;
|
||||
} else {
|
||||
contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
|
||||
smallIconId = android.R.drawable.stat_sys_warning;
|
||||
}
|
||||
|
||||
Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
|
||||
dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
dialogIntent.setPackage("com.android.settings");
|
||||
// Notification will be sent individually to all users. The activity should start as
|
||||
// whichever user is current when it starts.
|
||||
PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
|
||||
|
||||
Notification noti = new Notification.Builder(mContext)
|
||||
.setSmallIcon(smallIconId)
|
||||
.setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
|
||||
.setContentText(contentText)
|
||||
.setContentIntent(notifyIntent)
|
||||
.setPriority(Notification.PRIORITY_HIGH)
|
||||
.setShowWhen(false)
|
||||
.build();
|
||||
|
||||
// If this is a boot intent, this will fire for each user. But if this is a storage changed
|
||||
// intent, it will fire once, so we need to notify all users.
|
||||
if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
|
||||
UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
for (UserInfo user : um.getUsers()) {
|
||||
notificationManager.notifyAsUser(
|
||||
null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
|
||||
}
|
||||
} else {
|
||||
notificationManager.notifyAsUser(
|
||||
null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param adminReceiver The admin to add
|
||||
* @param refreshing true = update an active admin, no error
|
||||
|
Reference in New Issue
Block a user