diff options
author | Joey Grover <joeygrover@gmail.com> | 2017-03-23 09:23:40 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-23 09:23:40 -0400 |
commit | b7cfd8845f814a3b5d9f91c725bb75253b6f3f54 (patch) | |
tree | 31b7ced994abbbc547d3aa7a47ce1c6c9fe4e3c8 | |
parent | 874191b33d313cc44137a5dd782fa11364d3c26a (diff) | |
parent | 2badb4109593ee6f97907307129e3820069da5da (diff) | |
download | sdl_android-b7cfd8845f814a3b5d9f91c725bb75253b6f3f54.tar.gz |
Merge pull request #436 from smartdevicelink/feature/rsvp_default_security
Rsvp tiered security levels
5 files changed, 221 insertions, 5 deletions
diff --git a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java index 7a91c8cee..272c1878d 100644 --- a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java +++ b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java @@ -59,12 +59,14 @@ public class SdlConnection implements IProtocolListener, ITransportListener { //Let's check if we can even do multiplexing
if(transportConfig.getTransportType() == TransportType.MULTIPLEX){
ComponentName tempCompName = SdlBroadcastReceiver.consumeQueuedRouterService();
+ MultiplexTransportConfig multiConfig = (MultiplexTransportConfig)transportConfig;
if(tempCompName!=null){
- vlad =new RouterServiceValidator(((MultiplexTransportConfig)transportConfig).getContext(),tempCompName);
+ vlad =new RouterServiceValidator(multiConfig.getContext(),tempCompName);
}else{
- vlad =new RouterServiceValidator(((MultiplexTransportConfig)transportConfig).getContext());
+ vlad =new RouterServiceValidator(multiConfig.getContext());
}
//vlad.setFlags(RouterServiceValidator.FLAG_DEBUG_VERSION_CHECK);
+ vlad.setSecurityLevel(multiConfig.getSecurityLevel());
}
constructor(transportConfig,vlad);
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransportConfig.java b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransportConfig.java index b15a6cbb9..82fadbee2 100644 --- a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransportConfig.java +++ b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransportConfig.java @@ -7,9 +7,33 @@ import android.content.Context; public class MultiplexTransportConfig extends BaseTransportConfig{ + /** + * Multiplexing security will be turned off. All router services will be trusted. + */ + public static final int FLAG_MULTI_SECURITY_OFF = 0x00; + /** + * Multiplexing security will be minimal. Only trusted router services will be used. Trusted router list will be obtain from + * server. List will be refreshed every <b>30 days</b> or during next connection session if an SDL enabled app has been + * installed or uninstalled. + */ + public static final int FLAG_MULTI_SECURITY_LOW = 0x10; + /** + * Multiplexing security will be on at a normal level. Only trusted router services will be used. Trusted router list will be obtain from + * server. List will be refreshed every <b>7 days</b> or during next connection session if an SDL enabled app has been + * installed or uninstalled. + */ + public static final int FLAG_MULTI_SECURITY_MED = 0x20; + /** + * Multiplexing security will be very strict. Only trusted router services installed from trusted app stores will + * be used. Trusted router list will be obtain from server. List will be refreshed every <b>7 days</b> + * or during next connection session if an SDL enabled app has been installed or uninstalled. + */ + public static final int FLAG_MULTI_SECURITY_HIGH = 0x30; + Context context; String appId; ComponentName service; + int securityLevel; @@ -17,8 +41,14 @@ public class MultiplexTransportConfig extends BaseTransportConfig{ public MultiplexTransportConfig(Context context, String appId) { this.context = context; this.appId = appId; + this.securityLevel = FLAG_MULTI_SECURITY_MED; } + public MultiplexTransportConfig(Context context, String appId, int securityLevel) { + this.context = context; + this.appId = appId; + this.securityLevel = securityLevel; + } /** * Overridden abstract method which returns specific type of this transport configuration. @@ -45,7 +75,13 @@ public class MultiplexTransportConfig extends BaseTransportConfig{ this.service = service; } + public void setSecurityLevel(int securityLevel){ + this.securityLevel = securityLevel; + } + public int getSecurityLevel(){ + return securityLevel; + } } diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java b/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java index 081fb01c8..6703232d5 100644 --- a/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java +++ b/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java @@ -53,12 +53,13 @@ public class RouterServiceValidator { private static final String JSON_APP_VERSION_TAG = "version"; - private static final long REFRESH_TRUSTED_APP_LIST_TIME = 3600000 * 24 * 7; // A week in ms + private static final long REFRESH_TRUSTED_APP_LIST_TIME_DAY = 3600000 * 24; // A day in ms private static final String SDL = "sdl"; private static final String SDL_PACKAGE_LIST = "sdl_package_list"; private static final String SDL_PACKAGE_LIST_TIMESTAMP = "sdl_package_list_timestamp"; private static final String SDL_LAST_REQUEST = "sdl_last_request"; + private static final String SDL_RSVP_SECURITY_LEVEL = "sdl_rsvp_security_level"; //Flags to aid in debugging and production checks @@ -84,6 +85,7 @@ public class RouterServiceValidator { private ComponentName service;//This is how we can save different routers over another in a waterfall method if we choose to. + private static int securityLevel = -1; public RouterServiceValidator(Context context){ this.context = context; @@ -100,6 +102,15 @@ public class RouterServiceValidator { * @return whether or not the currently running router service can be trusted. */ public boolean validate(){ + + if(securityLevel == -1){ + securityLevel = getSecurityLevel(context); + } + + if(securityLevel == MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF){ //If security isn't an issue, just return true; + return true; + } + PackageManager pm = context.getPackageManager(); //Grab the package for the currently running router service. We need this call regardless of if we are in debug mode or not. String packageName = null; @@ -159,7 +170,8 @@ public class RouterServiceValidator { } private boolean shouldOverrideInstalledFrom(){ - return (this.inDebugMode && ((this.flags & FLAG_DEBUG_INSTALLED_FROM_CHECK) != FLAG_DEBUG_INSTALLED_FROM_CHECK)); + return securityLevel< MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH + || (this.inDebugMode && ((this.flags & FLAG_DEBUG_INSTALLED_FROM_CHECK) != FLAG_DEBUG_INSTALLED_FROM_CHECK)); } @SuppressWarnings("unused") @@ -178,6 +190,23 @@ public class RouterServiceValidator { this.flags = flags; } + public void setSecurityLevel(int securityLevel){ + RouterServiceValidator.securityLevel = securityLevel; + cacheSecurityLevel(this.context,securityLevel); + } + + protected static long getRefreshRate(){ + switch(securityLevel){ + case MultiplexTransportConfig.FLAG_MULTI_SECURITY_LOW: + return 30 * REFRESH_TRUSTED_APP_LIST_TIME_DAY; + case MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH: + case MultiplexTransportConfig.FLAG_MULTI_SECURITY_MED: + default: + return 7 * REFRESH_TRUSTED_APP_LIST_TIME_DAY; + + } + } + /** * This method will find which router service is running. Use that info to find out more about that app and service. * It will store the found service for later use and return the package name if found. @@ -371,6 +400,12 @@ public class RouterServiceValidator { if(context == null){ return false; } + else if(getSecurityLevel(context) == MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF){ //If security is off, we can just return now + if(listCallback!=null){ + listCallback.onListObtained(true); + } + return false; + } pendingListRefresh = true; //Might want to store a flag letting this class know a request is currently pending @@ -397,7 +432,7 @@ public class RouterServiceValidator { try {object.put(JSON_PUT_ARRAY_TAG, array);} catch (JSONException e) {e.printStackTrace();} - if(!forceRefresh && (System.currentTimeMillis()-getTrustedAppListTimeStamp(context))<REFRESH_TRUSTED_APP_LIST_TIME){ + if(!forceRefresh && (System.currentTimeMillis()-getTrustedAppListTimeStamp(context))<getRefreshRate()){ if(object.toString().equals(getLastRequest(context))){ //Our list should still be ok for now so we will skip the request pendingListRefresh = false; @@ -560,6 +595,25 @@ public class RouterServiceValidator { } return null; } + + protected static boolean cacheSecurityLevel(Context context, int securityLevel){ + if(context!=null){ + SharedPreferences pref = context.getSharedPreferences(SDL, Context.MODE_PRIVATE); + SharedPreferences.Editor prefAdd = pref.edit(); + prefAdd.putInt(SDL_RSVP_SECURITY_LEVEL, securityLevel); + return prefAdd.commit(); + } + return false; + } + + protected static int getSecurityLevel(Context context){ + if(context!=null){ + SharedPreferences pref = context.getSharedPreferences(SDL, Context.MODE_PRIVATE); + return pref.getInt(SDL_RSVP_SECURITY_LEVEL, MultiplexTransportConfig.FLAG_MULTI_SECURITY_MED); + } + return MultiplexTransportConfig.FLAG_MULTI_SECURITY_MED; + } + /** * Class that holds all the info we want to send/receive from the validation server */ diff --git a/sdl_android_tests/src/com/smartdevicelink/test/transport/MultiplexTransportConfigTests.java b/sdl_android_tests/src/com/smartdevicelink/test/transport/MultiplexTransportConfigTests.java new file mode 100644 index 000000000..c4bfad6cc --- /dev/null +++ b/sdl_android_tests/src/com/smartdevicelink/test/transport/MultiplexTransportConfigTests.java @@ -0,0 +1,24 @@ +package com.smartdevicelink.test.transport; + +import com.smartdevicelink.transport.MultiplexTransportConfig; + +import android.test.AndroidTestCase; + +public class MultiplexTransportConfigTests extends AndroidTestCase { + + + public void testDefaultSecurity(){ + MultiplexTransportConfig config = new MultiplexTransportConfig(this.mContext, "2341"); + assertEquals(config.getSecurityLevel(), MultiplexTransportConfig.FLAG_MULTI_SECURITY_MED); + } + + public void testSettingSecurity(){ + MultiplexTransportConfig config = new MultiplexTransportConfig(this.mContext, "2341", MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + assertEquals(config.getSecurityLevel(), MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + + config = new MultiplexTransportConfig(this.mContext, "2341"); + config.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + assertEquals(config.getSecurityLevel(), MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + } + +} diff --git a/sdl_android_tests/src/com/smartdevicelink/transport/RSVTestCase.java b/sdl_android_tests/src/com/smartdevicelink/transport/RSVTestCase.java index 824071b8b..03abbc7f4 100644 --- a/sdl_android_tests/src/com/smartdevicelink/transport/RSVTestCase.java +++ b/sdl_android_tests/src/com/smartdevicelink/transport/RSVTestCase.java @@ -1,5 +1,8 @@ package com.smartdevicelink.transport; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.List; import org.json.JSONArray; @@ -16,6 +19,11 @@ import com.smartdevicelink.util.HttpRequestTask.HttpRequestTaskCallback; public class RSVTestCase extends AndroidTestCase { private static final String TAG = "RSVTestCase"; + + private static final long REFRESH_TRUSTED_APP_LIST_TIME_DAY = 3600000 * 24; // A day in ms + private static final long REFRESH_TRUSTED_APP_LIST_TIME_WEEK = REFRESH_TRUSTED_APP_LIST_TIME_DAY * 7; // A week in ms + private static final long REFRESH_TRUSTED_APP_LIST_TIME_MONTH = REFRESH_TRUSTED_APP_LIST_TIME_DAY * 30; // A ~month in ms + RouterServiceValidator rsvp; /** * Set this boolean if you want to test the actual validation of router service @@ -74,6 +82,96 @@ public class RSVTestCase extends AndroidTestCase { } } + public void testSecuritySetting(){ + + RouterServiceValidator rsvp = new RouterServiceValidator(this.mContext); //Use a locally scoped instance + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + + try{ + Field securityLevelField = RouterServiceValidator.class.getDeclaredField("securityLevel"); + securityLevelField.setAccessible(true); + assertEquals(securityLevelField.get(rsvp),MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + }catch(NoSuchFieldException e1){ + fail(e1.getMessage()); + }catch( IllegalAccessException e2){ + fail(e2.getMessage()); + } + assertEquals(RouterServiceValidator.getSecurityLevel(mContext), MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + } + + public void testHighSecurity(){ + RouterServiceValidator rsvp = new RouterServiceValidator(this.mContext); //Use a locally scoped instance + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); + rsvp.setFlags(RouterServiceValidator.FLAG_DEBUG_INSTALLED_FROM_CHECK); + + assertTrue(checkShouldOverrideInstalledFrom(rsvp,false)); + + assertEquals(RouterServiceValidator.getRefreshRate(), REFRESH_TRUSTED_APP_LIST_TIME_WEEK); + + assertTrue(RouterServiceValidator.createTrustedListRequest(mContext, true, null, null)); + + } + + public void testMediumSecurity(){ + RouterServiceValidator rsvp = new RouterServiceValidator(this.mContext); //Use a locally scoped instance + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_MED); + rsvp.setFlags(RouterServiceValidator.FLAG_DEBUG_INSTALLED_FROM_CHECK); + + assertTrue(checkShouldOverrideInstalledFrom(rsvp,true)); + + assertEquals(RouterServiceValidator.getRefreshRate(), REFRESH_TRUSTED_APP_LIST_TIME_WEEK); + + assertTrue(RouterServiceValidator.createTrustedListRequest(mContext, true, null, null)); + + } + + public void testLowSecurity(){ + RouterServiceValidator rsvp = new RouterServiceValidator(this.mContext); //Use a locally scoped instance + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_LOW); + rsvp.setFlags(RouterServiceValidator.FLAG_DEBUG_INSTALLED_FROM_CHECK); + + assertTrue(checkShouldOverrideInstalledFrom(rsvp,true)); + + assertEquals(RouterServiceValidator.getRefreshRate(), REFRESH_TRUSTED_APP_LIST_TIME_MONTH); + + assertTrue(RouterServiceValidator.createTrustedListRequest(mContext, true, null, null)); + + } + + public void testNoSecurity(){ + RouterServiceValidator rsvp = new RouterServiceValidator(this.mContext); //Use a locally scoped instance + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF); + rsvp.setFlags(RouterServiceValidator.FLAG_DEBUG_INSTALLED_FROM_CHECK); + + assertTrue(checkShouldOverrideInstalledFrom(rsvp,true)); + + assertEquals(RouterServiceValidator.getRefreshRate(), REFRESH_TRUSTED_APP_LIST_TIME_WEEK); + + assertFalse(RouterServiceValidator.createTrustedListRequest(mContext, true, null, null)); + + //This should always return true + assertTrue(rsvp.validate()); + + } + + public boolean checkShouldOverrideInstalledFrom(RouterServiceValidator rsvp, boolean shouldOverride){ + try{ + Method shouldOverrideInstalledFrom = RouterServiceValidator.class.getDeclaredMethod("shouldOverrideInstalledFrom"); + shouldOverrideInstalledFrom.setAccessible(true); + boolean should = (Boolean)shouldOverrideInstalledFrom.invoke(rsvp); + + return shouldOverride == should; + + }catch(NoSuchMethodException e1){ + fail(e1.getMessage()); + }catch( IllegalAccessException e2){ + fail(e2.getMessage()); + }catch( InvocationTargetException e3){ + fail(e3.getMessage()); + } + return false; + } + public void testJsonRecovery(){ assertNotNull(rsvp.stringToJson(null)); assertNotNull(rsvp.stringToJson("asdf235vq32{]]")); @@ -136,6 +234,7 @@ public class RSVTestCase extends AndroidTestCase { rsvp = new RouterServiceValidator(this.mContext); rsvp.setFlags(RouterServiceValidator.FLAG_DEBUG_INSTALLED_FROM_CHECK); + rsvp.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH); PackageManager packageManager = mContext.getPackageManager(); List<PackageInfo> packages = packageManager.getInstalledPackages(0); @@ -209,6 +308,7 @@ public class RSVTestCase extends AndroidTestCase { * Test to check that we can save our last request which actually houses all the previous known sdl enabled apps */ public void testRequestChange(){ + RouterServiceValidator.setLastRequest(mContext, null); assertNull(RouterServiceValidator.getLastRequest(mContext)); String test = "{\"response\": {\"com.livio.sdl\" : { \"versionBlacklist\":[] }, \"com.lexus.tcapp\" : { \"versionBlacklist\":[] }, \"com.toyota.tcapp\" : { \"versionBlacklist\": [] } , \"com.sdl.router\":{\"versionBlacklist\": [] },\"com.ford.fordpass\" : { \"versionBlacklist\":[] } }}"; JSONObject object = null; |