mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 757646 - Throw from NSSBridge if Master password is set. r=rnewman,gbrown
This commit is contained in:
parent
cdc8708f89
commit
5ee0b8bb71
@ -29,6 +29,13 @@ public interface Actions {
|
|||||||
public void blockUntilClear(long millis);
|
public void blockUntilClear(long millis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an event to Gecko.
|
||||||
|
*
|
||||||
|
* @param geckoEvent The geckoEvent JSONObject's type
|
||||||
|
*/
|
||||||
|
void sendGeckoEvent(String geckoEvent, String data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for a gecko event to be sent from the Gecko instance.
|
* Listens for a gecko event to be sent from the Gecko instance.
|
||||||
* The returned object can be used to test if the event has been
|
* The returned object can be used to test if the event has been
|
||||||
|
@ -13,6 +13,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.Long;
|
import java.lang.Long;
|
||||||
|
import java.lang.NoSuchMethodException;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -180,6 +181,20 @@ public class FennecNativeActions implements Actions {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendGeckoEvent(String geckoEvent, String data) {
|
||||||
|
try {
|
||||||
|
Method cbe = mGe.getMethod("createBroadcastEvent", String.class, String.class);
|
||||||
|
Object event = cbe.invoke(null, geckoEvent, data);
|
||||||
|
mSendGE.invoke(null, event);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
FennecNativeDriver.log(LogLevel.ERROR, e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
FennecNativeDriver.log(LogLevel.ERROR, e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
FennecNativeDriver.log(LogLevel.ERROR, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DrawListenerProxy implements InvocationHandler {
|
class DrawListenerProxy implements InvocationHandler {
|
||||||
private final PaintExpecter mPaintExpecter;
|
private final PaintExpecter mPaintExpecter;
|
||||||
|
|
||||||
|
@ -15,49 +15,37 @@ public class NSSBridge {
|
|||||||
private static native String nativeEncrypt(String aDb, String aValue);
|
private static native String nativeEncrypt(String aDb, String aValue);
|
||||||
private static native String nativeDecrypt(String aDb, String aValue);
|
private static native String nativeDecrypt(String aDb, String aValue);
|
||||||
|
|
||||||
static public String encrypt(Context context, String aValue) {
|
static public String encrypt(Context context, String aValue)
|
||||||
|
throws Exception {
|
||||||
String resourcePath = context.getPackageResourcePath();
|
String resourcePath = context.getPackageResourcePath();
|
||||||
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
||||||
|
|
||||||
String res = "";
|
String path = GeckoProfile.get(context).getDir().toString();
|
||||||
try {
|
return nativeEncrypt(path, aValue);
|
||||||
String path = GeckoProfile.get(context).getDir().toString();
|
|
||||||
res = nativeEncrypt(path, aValue);
|
|
||||||
} catch(Exception ex) { }
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public String encrypt(Context context, String profilePath, String aValue) {
|
static public String encrypt(Context context, String profilePath, String aValue)
|
||||||
|
throws Exception {
|
||||||
String resourcePath = context.getPackageResourcePath();
|
String resourcePath = context.getPackageResourcePath();
|
||||||
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
||||||
|
|
||||||
String res = "";
|
return nativeEncrypt(profilePath, aValue);
|
||||||
try {
|
|
||||||
res = nativeEncrypt(profilePath, aValue);
|
|
||||||
} catch(Exception ex) { }
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public String decrypt(Context context, String aValue) {
|
static public String decrypt(Context context, String aValue)
|
||||||
|
throws Exception {
|
||||||
String resourcePath = context.getPackageResourcePath();
|
String resourcePath = context.getPackageResourcePath();
|
||||||
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
||||||
|
|
||||||
String res = "";
|
String path = GeckoProfile.get(context).getDir().toString();
|
||||||
try {
|
return nativeDecrypt(path, aValue);
|
||||||
String path = GeckoProfile.get(context).getDir().toString();
|
|
||||||
res = nativeDecrypt(path, aValue);
|
|
||||||
} catch(Exception ex) { }
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public String decrypt(Context context, String profilePath, String aValue) {
|
static public String decrypt(Context context, String profilePath, String aValue)
|
||||||
|
throws Exception {
|
||||||
String resourcePath = context.getPackageResourcePath();
|
String resourcePath = context.getPackageResourcePath();
|
||||||
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
GeckoAppShell.loadNSSLibs(context, resourcePath);
|
||||||
|
|
||||||
String res = "";
|
return nativeDecrypt(profilePath, aValue);
|
||||||
try {
|
|
||||||
res = nativeDecrypt(profilePath, aValue);
|
|
||||||
} catch(Exception ex) { }
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,6 @@ public abstract class GeckoProvider extends ContentProvider {
|
|||||||
// call to Gecko. Gecko will handle building the database file correctly, as well as any
|
// call to Gecko. Gecko will handle building the database file correctly, as well as any
|
||||||
// migrations that are necessary
|
// migrations that are necessary
|
||||||
if (dbNeedsSetup) {
|
if (dbNeedsSetup) {
|
||||||
Log.i(mLogTag, "Sending init to gecko");
|
|
||||||
bridge = null;
|
bridge = null;
|
||||||
initGecko();
|
initGecko();
|
||||||
}
|
}
|
||||||
@ -154,7 +153,6 @@ public abstract class GeckoProvider extends ContentProvider {
|
|||||||
|
|
||||||
private SQLiteBridge getDatabaseForProfile(String profile) {
|
private SQLiteBridge getDatabaseForProfile(String profile) {
|
||||||
if (TextUtils.isEmpty(profile)) {
|
if (TextUtils.isEmpty(profile)) {
|
||||||
Log.d(mLogTag, "No profile provided, using default");
|
|
||||||
profile = BrowserContract.DEFAULT_PROFILE;
|
profile = BrowserContract.DEFAULT_PROFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +165,6 @@ public abstract class GeckoProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(mLogTag, "Successfully created database helper for profile: " + profile);
|
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,18 +178,15 @@ public abstract class GeckoProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(mLogTag, "Successfully created database helper for path: " + profilePath);
|
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDatabasePathForProfile(String profile) {
|
private String getDatabasePathForProfile(String profile) {
|
||||||
File profileDir = GeckoProfile.get(mContext, profile).getDir();
|
File profileDir = GeckoProfile.get(mContext, profile).getDir();
|
||||||
if (profileDir == null) {
|
if (profileDir == null) {
|
||||||
Log.d(mLogTag, "Couldn't find directory for profile: " + profile);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(mLogTag, "Using path: " + profileDir.getPath());
|
|
||||||
String databasePath = new File(profileDir, mDBName).getAbsolutePath();
|
String databasePath = new File(profileDir, mDBName).getAbsolutePath();
|
||||||
return databasePath;
|
return databasePath;
|
||||||
}
|
}
|
||||||
|
@ -203,12 +203,23 @@ public class PasswordsProvider extends GeckoProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String result = "";
|
String result = "";
|
||||||
if (encrypt) {
|
try {
|
||||||
if (profilePath != null) result = NSSBridge.encrypt(mContext, profilePath, initialValue);
|
if (encrypt) {
|
||||||
else result = NSSBridge.encrypt(mContext, initialValue);
|
if (profilePath != null) {
|
||||||
} else {
|
result = NSSBridge.encrypt(mContext, profilePath, initialValue);
|
||||||
if (profilePath != null) result = NSSBridge.decrypt(mContext, profilePath, initialValue);
|
} else {
|
||||||
else result = NSSBridge.decrypt(mContext, initialValue);
|
result = NSSBridge.encrypt(mContext, initialValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (profilePath != null) {
|
||||||
|
result = NSSBridge.decrypt(mContext, profilePath, initialValue);
|
||||||
|
} else {
|
||||||
|
result = NSSBridge.decrypt(mContext, initialValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(getLogTag(), "Error in NSSBridge");
|
||||||
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,16 @@ import android.net.Uri;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class testPasswordEncrypt extends BaseTest {
|
public class testPasswordEncrypt extends BaseTest {
|
||||||
public void testPasswordEncrypt() {
|
public void testPasswordEncrypt() {
|
||||||
setTestType("mochitest");
|
setTestType("mochitest");
|
||||||
Context context = (Context)getActivity();
|
Context context = (Context)getActivity();
|
||||||
ContentResolver cr = context.getContentResolver();
|
ContentResolver cr = context.getContentResolver();
|
||||||
|
mAsserter.isnot(cr, null, "Found a content resolver");
|
||||||
ContentValues cvs = new ContentValues();
|
ContentValues cvs = new ContentValues();
|
||||||
|
|
||||||
Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("Gecko:Ready");
|
Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("Gecko:Ready");
|
||||||
@ -77,6 +82,24 @@ public class testPasswordEncrypt extends BaseTest {
|
|||||||
list.moveToFirst();
|
list.moveToFirst();
|
||||||
decryptedP = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
|
decryptedP = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
|
||||||
mAsserter.is(decryptedP, "password2", "Password was encrypted when updating");
|
mAsserter.is(decryptedP, "password2", "Password was encrypted when updating");
|
||||||
|
|
||||||
|
// Trying to store a password while master password is enabled should throw,
|
||||||
|
// but because Android can't send Exceptions across processes
|
||||||
|
// it just results in a null uri/cursor being returned.
|
||||||
|
toggleMasterPassword("password");
|
||||||
|
try {
|
||||||
|
uri = cr.insert(passwordUri, cvs);
|
||||||
|
mAsserter.is(uri, null, "Storing a password while MP was set should fail");
|
||||||
|
|
||||||
|
Cursor c = cr.query(passwordUri, null, null, null, null);
|
||||||
|
mAsserter.is(c, null, "Querying passwords while MP was set should fail");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// Password provider currently can not throw across process
|
||||||
|
// so we should not catch this exception here
|
||||||
|
mAsserter.ok(false, "Caught exception", ex.toString());
|
||||||
|
}
|
||||||
|
toggleMasterPassword("password");
|
||||||
|
|
||||||
} catch(ClassNotFoundException ex) {
|
} catch(ClassNotFoundException ex) {
|
||||||
mAsserter.ok(false, "Error getting class", ex.toString());
|
mAsserter.ok(false, "Error getting class", ex.toString());
|
||||||
return;
|
return;
|
||||||
@ -95,6 +118,22 @@ public class testPasswordEncrypt extends BaseTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void toggleMasterPassword(String passwd) {
|
||||||
|
JSONObject jsonPref = new JSONObject();
|
||||||
|
try {
|
||||||
|
jsonPref.put("name", "privacy.masterpassword.enabled");
|
||||||
|
jsonPref.put("type", "string");
|
||||||
|
jsonPref.put("value", passwd);
|
||||||
|
mActions.sendGeckoEvent("Preferences:Set", jsonPref.toString());
|
||||||
|
} catch (Exception ex) { }
|
||||||
|
|
||||||
|
JSONArray getPrefData = new JSONArray();
|
||||||
|
getPrefData.put("privacy.masterpassword.enabled");
|
||||||
|
Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||||
|
mActions.sendGeckoEvent("Preferences:Get", getPrefData.toString());
|
||||||
|
contentEventExpecter.blockForEvent();
|
||||||
|
}
|
||||||
|
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user