diff options
author | Paul Lawrence <paullawrence@google.com> | 2014-03-21 20:40:46 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-03-21 20:40:46 +0000 |
commit | 717e0f5db7161ddfff98f21fe1cdb2a3b1a6c8b7 (patch) | |
tree | 18db70592799ce0cc57e57bd3b0aaef51a26bb35 | |
parent | a7efb93c1b4e717049b106312ff353cd95c74f0e (diff) | |
parent | 493e3e7e6523fd94cc1acae3e45935a1227d58c3 (diff) | |
download | frameworks_base-717e0f5db7161ddfff98f21fe1cdb2a3b1a6c8b7.zip frameworks_base-717e0f5db7161ddfff98f21fe1cdb2a3b1a6c8b7.tar.gz frameworks_base-717e0f5db7161ddfff98f21fe1cdb2a3b1a6c8b7.tar.bz2 |
Merge "Don't prompt at boot if we already did that when decrypting"
6 files changed, 173 insertions, 1 deletions
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index b97734e..4180860 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -694,6 +694,36 @@ public interface IMountService extends IInterface { return _result; } + public String getPassword() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + String _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_getPassword, _data, _reply, 0); + _reply.readException(); + _result = _reply.readString(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } + + public void clearPassword() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + String _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } + public StorageVolume[] getVolumeList() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); @@ -846,7 +876,11 @@ public interface IMountService extends IInterface { static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34; - static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 36; + static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 35; + + static final int TRANSACTION_getPassword = IBinder.FIRST_CALL_TRANSACTION + 36; + + static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37; /** * Cast an IBinder object into an IMountService interface, generating a @@ -1208,6 +1242,19 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } + case TRANSACTION_getPassword: { + data.enforceInterface(DESCRIPTOR); + String result = getPassword(); + reply.writeNoException(); + reply.writeString(result); + return true; + } + case TRANSACTION_clearPassword: { + data.enforceInterface(DESCRIPTOR); + clearPassword(); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1446,4 +1493,15 @@ public interface IMountService extends IInterface { * @return PasswordType */ public int getPasswordType() throws RemoteException; + + /** + * Get password from vold + * @return password or empty string + */ + public String getPassword() throws RemoteException; + + /** + * Securely clear password from vold + */ + public void clearPassword() throws RemoteException; } diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 91056f1..9501f92 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -28,6 +28,7 @@ interface ILockSettings { boolean checkPattern(in String pattern, int userId); void setLockPassword(in String password, int userId); boolean checkPassword(in String password, int userId); + boolean checkVoldPassword(int userId); boolean havePattern(int userId); boolean havePassword(int userId); void removeUser(int userId); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 2d79491..e5aaf7e 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -313,6 +313,20 @@ public class LockPatternUtils { } /** + * Check to see if vold already has the password. + * Note that this also clears vold's copy of the password. + * @return Whether the vold password matches or not. + */ + public boolean checkVoldPassword() { + final int userId = getCurrentOrCallingUserId(); + try { + return getLockSettings().checkVoldPassword(userId); + } catch (RemoteException re) { + return false; + } + } + + /** * Check to see if a password matches any of the passwords stored in the * password history. * diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java index 31e806c..3fc562c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java @@ -979,6 +979,13 @@ public class KeyguardViewMediator { return; } + if (mLockPatternUtils.checkVoldPassword()) { + if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted"); + // Without this, settings is not enabled until the lock screen first appears + hideLocked(); + return; + } + if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); showLocked(options); } diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index fe814fc..19e8083 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -30,7 +30,11 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.os.Binder; import android.os.Environment; +import android.os.IBinder; import android.os.RemoteException; +import android.os.storage.IMountService; +import android.os.ServiceManager; +import android.os.storage.StorageManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; @@ -79,6 +83,7 @@ public class LockSettingsService extends ILockSettings.Stub { private final Context mContext; private LockPatternUtils mLockPatternUtils; + private boolean mFirstCallToVold; public LockSettingsService(Context context) { mContext = context; @@ -86,6 +91,7 @@ public class LockSettingsService extends ILockSettings.Stub { mOpenHelper = new DatabaseHelper(mContext); mLockPatternUtils = new LockPatternUtils(context); + mFirstCallToVold = true; } public void systemReady() { @@ -347,6 +353,33 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override + public boolean checkVoldPassword(int userId) throws RemoteException { + if (!mFirstCallToVold) { + return false; + } + mFirstCallToVold = false; + + checkPasswordReadPermission(userId); + + // There's no guarantee that this will safely connect, but if it fails + // we will simply show the lock screen when we shouldn't, so relatively + // benign. There is an outside chance something nasty would happen if + // this service restarted before vold stales out the password in this + // case. The nastiness is limited to not showing the lock screen when + // we should, within the first minute of decrypting the phone if this + // service can't connect to vold, it restarts, and then the new instance + // does successfully connect. + final IMountService service = getMountService(); + String password = service.getPassword(); + service.clearPassword(); + if (service.getPasswordType() == StorageManager.CRYPT_TYPE_PATTERN) { + return checkPattern(password, userId); + } else { + return checkPassword(password, userId); + } + } + + @Override public void removeUser(int userId) { checkWritePermission(userId); @@ -524,4 +557,12 @@ public class LockSettingsService extends ILockSettings.Stub { Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, Secure.LOCK_SCREEN_OWNER_INFO }; + + private IMountService getMountService() { + final IBinder service = ServiceManager.getService("mount"); + if (service != null) { + return IMountService.Stub.asInterface(service); + } + return null; + } } diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index cd74fed..b6e0d5f 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -74,6 +74,7 @@ import com.google.android.collect.Lists; import com.google.android.collect.Maps; import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.DecoderException; import org.xmlpull.v1.XmlPullParserException; import java.io.File; @@ -573,6 +574,14 @@ class MountService extends IMountService.Stub } } + private boolean isReady() { + try { + return mConnectedSignal.await(0, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + return false; + } + } + private void handleSystemReady() { // Snapshot current volume states since it's not safe to call into vold // while holding locks. @@ -2081,6 +2090,19 @@ class MountService extends IMountService.Stub return new String(Hex.encodeHex(bytes)); } + private String fromHex(String hexPassword) { + if (hexPassword == null) { + return null; + } + + try { + byte[] bytes = Hex.decodeHex(hexPassword.toCharArray()); + return new String(bytes, StandardCharsets.UTF_8); + } catch (DecoderException e) { + return null; + } + } + @Override public int decryptStorage(String password) { if (TextUtils.isEmpty(password)) { @@ -2230,6 +2252,35 @@ class MountService extends IMountService.Stub } @Override + public String getPassword() throws RemoteException { + if (!isReady()) { + return new String(); + } + + final NativeDaemonEvent event; + try { + event = mConnector.execute("cryptfs", "getpw"); + return fromHex(event.getMessage()); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public void clearPassword() throws RemoteException { + if (!isReady()) { + return; + } + + final NativeDaemonEvent event; + try { + event = mConnector.execute("cryptfs", "clearpw"); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override public int mkdirs(String callingPkg, String appPath) { final int userId = UserHandle.getUserId(Binder.getCallingUid()); final UserEnvironment userEnv = new UserEnvironment(userId); |