Loading core/java/android/os/storage/IMountService.java +59 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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; } core/java/com/android/internal/widget/ILockSettings.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/com/android/internal/widget/LockPatternUtils.java +14 −0 Original line number Diff line number Diff line Loading @@ -332,6 +332,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. Loading packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +7 −0 Original line number Diff line number Diff line Loading @@ -981,6 +981,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); } Loading services/core/java/com/android/server/LockSettingsService.java +59 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -86,6 +91,7 @@ public class LockSettingsService extends ILockSettings.Stub { mOpenHelper = new DatabaseHelper(mContext); mLockPatternUtils = new LockPatternUtils(context); mFirstCallToVold = true; } public void systemReady() { Loading Loading @@ -346,6 +352,51 @@ public class LockSettingsService extends ILockSettings.Stub { return true; } @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 (password == null) { return false; } try { if (mLockPatternUtils.isLockPatternEnabled()) { if (checkPattern(password, userId)) { return true; } } } catch (Exception e) { } try { if (mLockPatternUtils.isLockPasswordEnabled()) { if (checkPassword(password, userId)) { return true; } } } catch (Exception e) { } return false; } @Override public void removeUser(int userId) { checkWritePermission(userId); Loading Loading @@ -524,4 +575,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; } } Loading
core/java/android/os/storage/IMountService.java +59 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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; }
core/java/com/android/internal/widget/ILockSettings.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/com/android/internal/widget/LockPatternUtils.java +14 −0 Original line number Diff line number Diff line Loading @@ -332,6 +332,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. Loading
packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +7 −0 Original line number Diff line number Diff line Loading @@ -981,6 +981,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); } Loading
services/core/java/com/android/server/LockSettingsService.java +59 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -86,6 +91,7 @@ public class LockSettingsService extends ILockSettings.Stub { mOpenHelper = new DatabaseHelper(mContext); mLockPatternUtils = new LockPatternUtils(context); mFirstCallToVold = true; } public void systemReady() { Loading Loading @@ -346,6 +352,51 @@ public class LockSettingsService extends ILockSettings.Stub { return true; } @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 (password == null) { return false; } try { if (mLockPatternUtils.isLockPatternEnabled()) { if (checkPattern(password, userId)) { return true; } } } catch (Exception e) { } try { if (mLockPatternUtils.isLockPasswordEnabled()) { if (checkPassword(password, userId)) { return true; } } } catch (Exception e) { } return false; } @Override public void removeUser(int userId) { checkWritePermission(userId); Loading Loading @@ -524,4 +575,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; } }