am df42723d: Merge "Don\'t double prompt on booting encrypted device"

* commit 'df42723d6b717fd2882c98c930a0f93c75af2474':
  Don't double prompt on booting encrypted device
This commit is contained in:
Paul Lawrence
2014-04-01 15:11:31 +00:00
committed by Android Git Automerger
6 changed files with 192 additions and 2 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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() {
@@ -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);
@@ -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;
}
}

View File

@@ -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.
@@ -2075,12 +2084,25 @@ class MountService extends IMountService.Stub
private String toHex(String password) {
if (password == null) {
return null;
return new String();
}
byte[] bytes = password.getBytes(StandardCharsets.UTF_8);
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)) {
@@ -2229,6 +2251,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());