diff --git a/.DS_Store b/.DS_Store index 310236e..73e14d7 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/MVMCore/MVMCore.xcodeproj/project.pbxproj b/MVMCore/MVMCore.xcodeproj/project.pbxproj index fc847e7..71297bc 100644 --- a/MVMCore/MVMCore.xcodeproj/project.pbxproj +++ b/MVMCore/MVMCore.xcodeproj/project.pbxproj @@ -27,8 +27,6 @@ 88D1FBE11FCCCBA100338A3A /* MVMCoreMainSplitViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1FBDF1FCCCADC00338A3A /* MVMCoreMainSplitViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88D1FBE21FCCCBA500338A3A /* PanelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1FBE01FCCCB2C00338A3A /* PanelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; }; - AF26DDB51FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */; }; - AF26DDB71FCE802D004E8F65 /* DigiCertGlobalRootCA.cer in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */; }; AF43A5771FBA5B7C008E9347 /* MVMCoreJSONConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */; }; AF43A57B1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5791FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -71,10 +69,6 @@ AFBB96621FBA3A570008D868 /* MVMCoreRequestParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96491FBA3A560008D868 /* MVMCoreRequestParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; AFBB96631FBA3A570008D868 /* MVMCoreLoadRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964A1FBA3A560008D868 /* MVMCoreLoadRequestOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */; }; - AFBB96651FBA3A570008D868 /* MFSSLPinningHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AFBB96661FBA3A570008D868 /* MFSSLPinningHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */; }; - AFBB96671FBA3A570008D868 /* MFURLSessionChallengeResult.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AFBB96681FBA3A570008D868 /* MFURLSessionChallengeResult.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */; }; AFBB96691FBA3A570008D868 /* MVMCoreRequestParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96511FBA3A560008D868 /* MVMCoreRequestParameters.m */; }; AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96521FBA3A570008D868 /* MVMCoreLoadRequestOperation.m */; }; AFBB968B1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB966D1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -156,8 +150,6 @@ 88D1FBDF1FCCCADC00338A3A /* MVMCoreMainSplitViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreMainSplitViewProtocol.h; sourceTree = ""; }; 88D1FBE01FCCCB2C00338A3A /* PanelProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PanelProtocol.h; sourceTree = ""; }; AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer"; sourceTree = ""; }; - AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = DigiCertGlobalRootCA.cer; sourceTree = ""; }; AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreJSONConstants.h; sourceTree = ""; }; AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreJSONConstants.m; sourceTree = ""; }; AF43A5791FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreHardcodedStringsConstants.h; sourceTree = ""; }; @@ -203,10 +195,6 @@ AFBB96491FBA3A560008D868 /* MVMCoreRequestParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreRequestParameters.h; sourceTree = ""; }; AFBB964A1FBA3A560008D868 /* MVMCoreLoadRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreLoadRequestOperation.h; sourceTree = ""; }; AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreLoadHandler.m; sourceTree = ""; }; - AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFSSLPinningHandler.h; sourceTree = ""; }; - AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFSSLPinningHandler.m; sourceTree = ""; }; - AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFURLSessionChallengeResult.h; sourceTree = ""; }; - AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFURLSessionChallengeResult.m; sourceTree = ""; }; AFBB96511FBA3A560008D868 /* MVMCoreRequestParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreRequestParameters.m; sourceTree = ""; }; AFBB96521FBA3A570008D868 /* MVMCoreLoadRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreLoadRequestOperation.m; sourceTree = ""; }; AFBB966D1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreDismissViewControllerOperation.h; sourceTree = ""; }; @@ -356,15 +344,6 @@ path = Strings; sourceTree = ""; }; - AF26DDB11FCE7C76004E8F65 /* Certificates */ = { - isa = PBXGroup; - children = ( - AF26DDB61FCE802D004E8F65 /* DigiCertGlobalRootCA.cer */, - AF26DDB31FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer */, - ); - path = Certificates; - sourceTree = ""; - }; AF43A5941FBB700D008E9347 /* MainStructure */ = { isa = PBXGroup; children = ( @@ -445,7 +424,6 @@ children = ( AFFCFA601FCCC0D600FD0730 /* LoadingOverlay */, AFBB963C1FBA3A550008D868 /* FreeBee */, - AFBB964C1FBA3A560008D868 /* SSLPinning */, AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */, AFBB96391FBA3A550008D868 /* MVMCoreLoadHandler.h */, AFBB964B1FBA3A560008D868 /* MVMCoreLoadHandler.m */, @@ -476,18 +454,6 @@ path = FreeBee; sourceTree = ""; }; - AFBB964C1FBA3A560008D868 /* SSLPinning */ = { - isa = PBXGroup; - children = ( - AF26DDB11FCE7C76004E8F65 /* Certificates */, - AFBB964D1FBA3A560008D868 /* MFSSLPinningHandler.h */, - AFBB964E1FBA3A560008D868 /* MFSSLPinningHandler.m */, - AFBB964F1FBA3A560008D868 /* MFURLSessionChallengeResult.h */, - AFBB96501FBA3A560008D868 /* MFURLSessionChallengeResult.m */, - ); - path = SSLPinning; - sourceTree = ""; - }; AFBB966B1FBA3A9A0008D868 /* PresentationHandling */ = { isa = PBXGroup; children = ( @@ -645,12 +611,10 @@ AFBB96601FBA3A570008D868 /* MVMCoreLoadObject.h in Headers */, AF43A7061FC4D7A2008E9347 /* MVMCoreObject.h in Headers */, AFED77A11FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.h in Headers */, - AFBB96671FBA3A570008D868 /* MFURLSessionChallengeResult.h in Headers */, AFBB969F1FBA3A9A0008D868 /* MVMCoreAlertOperation.h in Headers */, AFBB965A1FBA3A570008D868 /* FreeBeeUrlObject.h in Headers */, AF43A71B1FC5BEBB008E9347 /* MVMCoreViewControllerProtocol.h in Headers */, AFBB96571FBA3A570008D868 /* FreeBeeAuthObject.h in Headers */, - AFBB96651FBA3A570008D868 /* MFSSLPinningHandler.h in Headers */, AFBB96381FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h in Headers */, AFBB96B01FBA3B590008D868 /* MVMCoreDispatchUtility.h in Headers */, 8876D5E81FB50AB000EB2E3D /* NSArray+MFConvenience.h in Headers */, @@ -744,10 +708,8 @@ files = ( AFBB96EB1FBA4A260008D868 /* canned.json in Resources */, AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */, - AF26DDB71FCE802D004E8F65 /* DigiCertGlobalRootCA.cer in Resources */, AFBB96561FBA3A570008D868 /* freebee.json in Resources */, AFBB96591FBA3A570008D868 /* freebeelaunchApp.json in Resources */, - AF26DDB51FCE7C76004E8F65 /* VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -778,7 +740,6 @@ 881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */, 30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */, 8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */, - AFBB96661FBA3A570008D868 /* MFSSLPinningHandler.m in Sources */, AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */, AFBB96581FBA3A570008D868 /* FreeBeeAuthObject.m in Sources */, AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */, @@ -791,7 +752,6 @@ AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */, AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */, AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */, - AFBB96681FBA3A570008D868 /* MFURLSessionChallengeResult.m in Sources */, AFBB965D1FBA3A570008D868 /* MFFreebeeHandler.m in Sources */, AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */, AFBB969E1FBA3A9A0008D868 /* MVMCoreAlertObject.m in Sources */, @@ -946,10 +906,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/../../SharedFrameworks", - "\"$(SRCROOT)/../../SharedFrameworks\"", - ); + FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks"; INFOPLIST_FILE = MVMCore/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -977,10 +934,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/../../SharedFrameworks", - "\"$(SRCROOT)/../../SharedFrameworks\"", - ); + FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks"; INFOPLIST_FILE = MVMCore/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; diff --git a/MVMCore/MVMCore.xcodeproj/xcuserdata/yangti5.xcuserdatad/xcschemes/xcschememanagement.plist b/MVMCore/MVMCore.xcodeproj/xcuserdata/yangti5.xcuserdatad/xcschemes/xcschememanagement.plist index acdb3cc..79ba96a 100644 --- a/MVMCore/MVMCore.xcodeproj/xcuserdata/yangti5.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/MVMCore/MVMCore.xcodeproj/xcuserdata/yangti5.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,10 +4,15 @@ SchemeUserState + MVMCore.xcscheme + + orderHint + 17 + MVMCore.xcscheme_^#shared#^_ orderHint - 11 + 6 diff --git a/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.h b/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.h index eadad96..d669629 100644 --- a/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.h +++ b/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.h @@ -15,11 +15,3 @@ extern NSString * const HardcodedOK; extern NSString * const HardcodedErrorCritical; extern NSString * const HardcodedErrorUnableToProcess; -// SSL Pinning error strings -extern NSString * const ERROR_SSL_TITLE; -extern NSString * const ERROR_SSL_MESSAGE_PREFIX_KEY; -extern NSString * const ERROR_SSL_MESSAGE_TITLE_KEY; -extern NSString * const ERROR_SSL_MESSAGE_POSTFIX_KEY; -extern NSString * const ERROR_SSL_UPDATE_TITLE_KEY; -extern NSString * const ERROR_SSL_UPDATE_MESSAGE_KEY; - diff --git a/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.m b/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.m index a1caf5d..e6c17f3 100644 --- a/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.m +++ b/MVMCore/MVMCore/Constants/MVMCoreHardcodedStringsConstants.m @@ -15,11 +15,3 @@ NSString * const HardcodedOK = @"okCaps"; NSString * const HardcodedErrorCritical = @"Error Message Critical Key"; NSString * const HardcodedErrorUnableToProcess = @"Error Message Unable To Process Request Key"; -// SSL Pinning error strings -NSString * const ERROR_SSL_TITLE = @"SSL Error Title"; -NSString * const ERROR_SSL_MESSAGE_PREFIX_KEY = @"SSL Error Message Prefix"; -NSString * const ERROR_SSL_MESSAGE_TITLE_KEY = @"SSL Error Message Title"; -NSString * const ERROR_SSL_MESSAGE_POSTFIX_KEY = @"SSL Error Message Postfix"; -NSString * const ERROR_SSL_UPDATE_TITLE_KEY = @"SSL Update Title"; -NSString * const ERROR_SSL_UPDATE_MESSAGE_KEY = @"SSL Update Message"; - diff --git a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.h b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.h index c2245f4..dc0daee 100644 --- a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.h +++ b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.h @@ -34,6 +34,7 @@ typedef void(^FreebeeLoadFinishedHandler)(MVMCoreOperation* _Nullable freebeeOpe - (void)enableFreeBeeForCurrentModule:(BOOL)enable; - (BOOL)isFreeBeeEnabledForCurrentModule; - (BOOL)isExcludedModule:(nullable NSString*)parentPageType; +- (BOOL)isAllowedPage:(nullable NSString*)pageType; - (void)printStatusDescription; diff --git a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.m b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.m index bace2f7..2a8d2cb 100644 --- a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.m +++ b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeHandler.m @@ -27,6 +27,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { FreeBeeCampaignStateExpired, }; +#define ENABLE_FREEBEE_LOCAL_TEST 0 @interface MFFreebeeHandler() @property(nonatomic, strong) NSString* authString; @@ -36,6 +37,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { @property(nonatomic, assign) FreeBeeCampaignState currentFreeBeeCampaignState; @property(nonatomic, strong) NSMutableArray* freeBeeUrls; @property(nonatomic, strong) NSArray* excludedModulesForFreeBee; +@property(nonatomic, strong) NSArray* enabledRootPagesForFreebee; @property(nonatomic, strong) NSMutableDictionary* configDictionary; @property(nonatomic) BOOL freeBeeEnabled; @@ -60,7 +62,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { - (FreeBeeCampaignState)processResponse:(NSData*)data withExtraParams:(NSDictionary*)extraParams; - (void)configureMFFreeBeeSession; -+ (NSData *)sendSynchronousRequest:(NSURL *)url +- (NSData *)sendSynchronousRequest:(NSURL *)url returningResponse:(__autoreleasing NSURLResponse **)response error:(__autoreleasing NSError **)error; @end @@ -78,7 +80,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { sharedHandler.freeBeeAuthObj = nil; sharedHandler.currentFreeBeeCampaignState = FreeBeeCampaignStateNotDetermined; sharedHandler.excludedModulesForFreeBee = nil; - sharedHandler.freeBeeEnabledForCurrentModule = YES; + sharedHandler.freeBeeEnabledForCurrentModule = NO; sharedHandler.requestTimeoutInterval = 1; sharedHandler.isFreeBeeServerEnabled = NO; @@ -109,7 +111,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { MVMCoreLog(@"FreeBee State Invalidated"); if (self.currentFreeBeeCampaignState != FreeBeeCampaignStateBusy) { - self.currentFreeBeeCampaignState = FreeBeeCampaignStateNotDetermined; [[MVMCoreSessionObject sharedGlobal].freeBeeSession invalidateAndCancel]; [MVMCoreSessionObject sharedGlobal].freeBeeSession = nil; @@ -117,16 +118,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { } - (void)processFreeBeeAuthRequestWithCompletionHandler:(nullable FreebeeLoadFinishedHandler)completionHandler { - - if ([self canProceedWithFreebeeAuthRequest]) { - - // check if self timer based mechanism can be used - if([self isExpired]) { - - [self invalidateFreeBeeState]; - } + + if ([self isExpired]) { + [self invalidateFreeBeeState]; } - [self processFreeBeeState:completionHandler]; } @@ -139,33 +134,26 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { } - (BOOL)isFreeBeeEnabled { - return self.freeBeeEnabled; } - (BOOL)isValidCampaign { - if (self.currentFreeBeeCampaignState == FreeBeeCampaignStateValid ) { - return YES; } - return NO; } - (BOOL)isExpired { - return [self.freeBeeAuthObj isExpired]; } - (void)enableFreeBeeForCurrentModule:(BOOL)enable { - if (self.isFreeBeeEnabled) self.freeBeeEnabledForCurrentModule = enable; } - (BOOL)isFreeBeeEnabledForCurrentModule { - return self.freeBeeEnabledForCurrentModule; } @@ -175,7 +163,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { return NO; if (parentPageType.length) { - NSPredicate* predicate = [NSPredicate predicateWithFormat:@"%@ =[cd] SELF", parentPageType]; NSArray* subArray = [self.excludedModulesForFreeBee filteredArrayUsingPredicate:predicate]; if (subArray.count) @@ -186,14 +173,22 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { return YES; } +- (BOOL)isAllowedPage:(nullable NSString*)pageType { + + if (!self.enabledRootPagesForFreebee.count) { + return NO; + } + if (pageType.length) { + return [self.enabledRootPagesForFreebee containsObject:pageType]; + } + return NO; +} + - (void)printStatusDescription { if ([[MFFreebeeHandler sharedHandler] isValidCampaign]) { - MVMCoreLog(@"FreeBee Valid Campaign"); - } - else { - + } else { MVMCoreLog(@"FreeBee Invalid Campaign"); } } @@ -240,27 +235,23 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { NSData* data = nil; NSDictionary* proxyDict = [self proxyDictionaryforUrl:url]; - if (YES == [self isFreeBeeEnabled] && - YES == [self isValidCampaign] && proxyDict && - YES == [self isFreeBeeEnabledForCurrentModule]) { - - MVMCoreLog(@"Free Data Url, %@", url); - - NSURLResponse* response = nil; - NSError* error = nil; - data = [self sendSynchronousRequest:url returningResponse:&response error:&error]; - - if(error) - data = nil; - - MVMCoreLog(@"freebee_dataWithContentsOfURL:Free Data, %lu", (unsigned long)data.length); - } - else { - + if ([self isFreeBeeEnabled] && + [self isValidCampaign] && proxyDict && + ![self isExpired] && [self isFreeBeeEnabledForCurrentModule]) { + + MVMCoreLog(@"Free Data Url, %@", url); + NSURLResponse* response = nil; + NSError* error = nil; + data = [self sendSynchronousRequest:url returningResponse:&response error:&error]; + + if (error) + data = nil; + + MVMCoreLog(@"freebee_dataWithContentsOfURL:Free Data, %lu", (unsigned long)data.length); + } else { data = [NSData dataWithContentsOfURL:url]; } return data; - } #pragma mark - FreeBee Registration @@ -273,7 +264,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { #endif if (module) { - // Enable for testing hardcoded response #if ENABLE_FREEBEE_LOCAL_TEST NSString *plistPath = [[MVMCoreUtility bundleForMVMCore] pathForResource:@"freebeelaunchApp" ofType:@"json"]; @@ -297,18 +287,17 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { NSDictionary* configDict = [module dictionaryForKey:@"freeBeeData"]; [self configureFreeBeeWithDict:configDict withSessionReset:NO]; self.excludedModulesForFreeBee = [module arrayForKey:@"disabledModules"]; + self.enabledRootPagesForFreebee = [module arrayForKey:@"enabledPages"]; NSString* timeOut = [module stringForKey:@"authRequestTimeOut"]; NSTimeInterval time = [timeOut doubleValue]; if (time > 0.f) self.requestTimeoutInterval = time; - } - else { + } else { [self configureFreeBeeWithDict:nil withSessionReset:NO]; } - } - else { + } else { [self configureFreeBeeWithDict:nil withSessionReset:NO]; } @@ -321,8 +310,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { [self updateWithConfigDictionary:configDict]; [self enableReachability:YES]; - } - else { + } else { [self invalidateFreeBeeState]; [self updateWithConfigDictionary:nil]; @@ -349,6 +337,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { break; case FreeBeeCampaignStateValid: + [self enableReachability:YES]; self.completionHandler(nil, YES); self.completionHandler = nil; //start a timer request @@ -366,9 +355,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { } - (void)processBusyState { - - if (nil == self.configDictionary) { - + if (!self.configDictionary) { MVMCoreLog(@"FreeBee Response failed with error configDictionary:Empty"); self.freeBeeAuthObj = nil; self.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid; @@ -398,9 +385,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { self.currentFreeBeeCampaignState = FreeBeeCampaignStateBusy; NSURLRequest* request = [self authRequestWithConfigDict:self.configDictionary]; - - if (request == nil) { - + if (!request) { [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:nil]; wSelf.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid; [self processFreeBeeState:nil]; @@ -414,14 +399,16 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { - (void)updateWithConfigDictionary:(nullable NSDictionary*)configDict { - if (configDict && configDict.count) + if (configDict && configDict.count) { self.configDictionary = [NSMutableDictionary dictionaryWithDictionary:configDict]; - else { + } else { [self.configDictionary removeAllObjects]; self.isFreeBeeServerEnabled = NO; self.freeBeeEnabled = NO; self.freeBeeEnabledForCurrentModule = NO; + self.enabledRootPagesForFreebee = nil; + self.excludedModulesForFreeBee = nil; } } @@ -458,7 +445,6 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { if (self.currentFreeBeeCampaignState == FreeBeeCampaignStateNotDetermined) return YES; - return NO; } @@ -466,16 +452,18 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { - (void)updateWithResponse:(NSData*)data Error:(NSError*)error ExtraParams:(NSDictionary*) extraParams { if (data.length > 0) { - self.currentFreeBeeCampaignState = [self processResponse:data withExtraParams:extraParams]; [self processFreeBeeState:nil]; - } else { - // Empty response. MVMCoreLog(@"FreeBee Auth Request failed with empty response"); self.currentFreeBeeCampaignState = FreeBeeCampaignStateInvalid; - [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:extraParams]; + + if (error.description) { + [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:@{@"description":error.description}]; + } else { + [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:extraParams]; + } [self processFreeBeeState:nil]; } self.freebeeOperation = nil; @@ -496,13 +484,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { if ([jsonDictionary isKindOfClass:[NSDictionary class]]) { if (!self.freeBeeAuthObj) { - //warning:this needs to be modified for multiple urls wSelf.freeBeeAuthObj = [[FreeBeeAuthObject alloc] init]; [wSelf.freeBeeAuthObj updateWithDictionary:jsonDictionary]; - } - else { - + } else { [wSelf.freeBeeAuthObj updateWithDictionary:jsonDictionary]; } @@ -515,9 +500,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { [logDict addEntriesFromDictionary:extraParams]; if ([self.freeBeeAuthObj isValidFreeBeeSessionAuthObject]) { - [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeSuccess" withExtraInfo:logDict]; - MVMCoreLog(@"FreeBee Response Validated"); [self configureMFFreeBeeSession]; return FreeBeeCampaignStateValid; @@ -531,11 +514,8 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { } if (error.description) { - [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:@{@"description":error.description}]; - } - else { - + } else { [MVMCoreLoggingHandler logWithDelegateWithObject:nil withName:@"freeBeeError" withExtraInfo:nil]; } @@ -545,7 +525,7 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { - (void)configureMFFreeBeeSession { MVMCoreLog(@"FreeBee Configure Session"); - + //Assign The new Session Configuration sice its not possible to modify the existing session, we need to MVMCoreSessionObject *sessionSingleton = [MVMCoreSessionObject sharedGlobal]; NSURLSession* session = sessionSingleton.session; @@ -586,11 +566,9 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { NSDictionary* campaignDictionary = [[MFFreebeeHandler sharedHandler] campaignHeaderforUrl:url]; if (campaignDictionary) { - [request addValue:campaignDictionary[@"Proxy-Authorization"] forHTTPHeaderField:@"Proxy-Authorization"]; } - - + [[session dataTaskWithRequest:request completionHandler:^(NSData* _data, NSURLResponse* _response, NSError* _error) { @@ -604,12 +582,10 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { dispatch_group_wait(group, DISPATCH_TIME_FOREVER); if (response) { - *response = resp; } if (error) { - *error = err; } @@ -620,22 +596,14 @@ typedef NS_ENUM(NSUInteger, FreeBeeCampaignState) { dispatch_async(dispatch_get_main_queue(), ^{ if (enable) { - _reachability = [Reachability reachabilityForInternetConnection]; - // Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the method reachabilityChanged will be called. - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityDidChange:) name:kReachabilityChangedNotification object:nil]; [_reachability startNotifier]; - } - else { - - if (_reachability) { - - [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil]; - [_reachability stopNotifier]; - _reachability = nil; - } + } else if (_reachability) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil]; + [_reachability stopNotifier]; + _reachability = nil; } }); } diff --git a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeOperation.m b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeOperation.m index f84e23d..d0ffbbd 100644 --- a/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeOperation.m +++ b/MVMCore/MVMCore/LoadHandling/FreeBee/MFFreebeeOperation.m @@ -11,7 +11,7 @@ @interface MFFreebeeOperation() -@property(nonatomic, strong) NSURLRequest* freeBeeAuthRequest; +@property(nonatomic, strong) NSURLRequest *freeBeeAuthRequest; @property(weak) id delegate; @property(nonatomic) dispatch_semaphore_t semaphore; @@ -52,21 +52,22 @@ NSURLRequest *request = self.freeBeeAuthRequest; if (request == nil) { - [self.delegate updateWithResponse:nil Error:nil ExtraParams:nil]; return; } MVMCoreLog(@"*********************************FreeBee Auth Call Start**********************************"); - NSDate* date = [NSDate date]; - NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date]; - + NSURLResponse *response = nil; NSError *error = nil; + + NSDate *date = [NSDate date]; NSData *data = [self sendSynchronousRequest:request returningResponse:&response error:&error]; + NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date]; + MVMCoreLog(@"Freebee Auth Call Request Time response for freebee is %f", interval); - NSDictionary *timeForRequest = @{@"ResponseTime":@(interval)}; - [self.delegate updateWithResponse:[data copy] Error:error ExtraParams:timeForRequest]; + NSDictionary *extraParams = @{@"ResponseTime":@(interval)}; + [self.delegate updateWithResponse:[data copy] Error:error ExtraParams:extraParams]; } - (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response @@ -93,12 +94,10 @@ dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); if (response) { - *response = resp; } if (error) { - *error = err; } diff --git a/MVMCore/MVMCore/LoadHandling/FreeBee/freebee.json b/MVMCore/MVMCore/LoadHandling/FreeBee/freebee.json index 4b1203e..4ef3d8b 100644 --- a/MVMCore/MVMCore/LoadHandling/FreeBee/freebee.json +++ b/MVMCore/MVMCore/LoadHandling/FreeBee/freebee.json @@ -1,14 +1,15 @@ { - "statusCode": 200, - "vidToken": "xlO5qbqZLp68J7OBHqumyN693FfDAdY6rC3T51haBxM=", - "sdAuthResp": [ - { - "urlId": "1", - "authRespCode": 1200, - "httpsProxyIP": "68.128.201.128", - "sdUrl": "mobile.vzw.com:443?vzSvc=xlO5qbqZLp68J7OBHqumyN693FfDAdY6rC3T51haBxM=&vispVzKey=70421425&vispIconFg=1&vispUsr=70421425:A4WgVNAcwIdx8EVgt4QjyQ==&vispAuthSid=CIAAACAKJwE&vispExpTime=1492803669&vispAuthKey=46700746&vispAuthSign=0.19.sC5AhLOaDdDXZWz3gYx0MoxjNJLxb6IcV-e5ZBxNS8s", - "sdConfExpiry": 1697567906, - "sdPort": 22779 - } - ] + "statusCode": 200, + "message": "Success", + "vidToken": "OAlTpG0WFQ_qKHdnjBQueUB_SjZk46rjTGxxSGppKd8=", + "sdAuthResp": [ + { + "urlId": "1", + "authRespCode": 1200, + "httpsProxyIP": "152.198.7.159", + "sdPort": 22779, + "sdUrl": "mobile-eqa6.vzw.com:443?vzSvc=OAlTpG0WFQ_qKHdnjBQueUB_SjZk46rjTGxxSGppKd8=&vispVzKey=44595039&vispIconFg=1&vispUsr=44595039:sNNHcJP2nYGtcuiCaVZcHQ==&vispAuthSid=CIAAACAKJwE&vispExpTime=1511370770&vispAuthKey=25858536&vispAuthSign=0.19._y9flLw7123TMhTcHUe7IVUmzJZK4MhC5kC3A6FTvXw", + "sdConfExpiry": 1512370770 + } + ] } diff --git a/MVMCore/MVMCore/LoadHandling/FreeBee/freebeelaunchApp.json b/MVMCore/MVMCore/LoadHandling/FreeBee/freebeelaunchApp.json index 0ac015a..1635f8f 100644 --- a/MVMCore/MVMCore/LoadHandling/FreeBee/freebeelaunchApp.json +++ b/MVMCore/MVMCore/LoadHandling/FreeBee/freebeelaunchApp.json @@ -14,12 +14,15 @@ "authUrls": [ { "urlId": "1", - "authUrl": "mobile.vzw.com:443" + "authUrl": "mobile-eqa6.vzw.com:443" } ] }, - "disabledModules": [ + "disabledModules": ["gridwall" ], + "enabledPages": ["billOverview","myData","accountLanding", "deviceLanding" + ], + "proxyServerUrl": "https://auth.svcs.verizon.com:22790/sd/v2/sdAuthorization/httpsProxy" } } diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.h b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.h index 7ccc0ed..95422cf 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.h @@ -62,7 +62,4 @@ // By default, returns continue loading and decides not to throw an error. + (BOOL)defaultHandleModuleError:(nonnull NSString *)module loadObject:(nonnull MVMCoreLoadObject *)loadObject error:(nonnull MVMCoreErrorObject *)error; -// Tracks that it has finished.. -+ (void)defaultLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController *)loadedViewController error:(nullable MVMCoreErrorObject *)error; - @end diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.m index bcd112b..aae485c 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadHandler.m @@ -14,7 +14,6 @@ #import "MFHardCodedServerResponse.h" #import "MFFreebeeHandler.h" #import "MVMCoreNavigationHandler.h" -#import "MFSSLPinningHandler.h" #import "MVMCoreLoadObject.h" #import "MVMCoreSessionObject.h" #import "MVMCoreJSONConstants.h" @@ -159,14 +158,7 @@ // Create and send post request, adding params as http body. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:timeOutInterval]; - - [request setHTTPMethod:@"POST"]; - [request setValue:@"no-cache, no-store" forHTTPHeaderField:@"Cache-Control"]; - - // Either adds the params to the body or the header. - [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - + [self setHeadersForRequest:request requestParameters:requestParameters]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; @@ -179,7 +171,7 @@ } // Adds request specific parameters - if (requestParameters.parameters.count > 0) { + if (requestParameters.parameters.count) { [parameters setObject:requestParameters.parameters forKey:@"RequestParams"]; } @@ -191,28 +183,28 @@ } //adding Free Bee header - if(YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabled] - && YES == [[MFFreebeeHandler sharedHandler] isValidCampaign]) { + if ([[MFFreebeeHandler sharedHandler] isFreeBeeEnabled] + && [[MFFreebeeHandler sharedHandler] isValidCampaign]) { + BOOL isAllowedPage = [[MFFreebeeHandler sharedHandler] isAllowedPage:requestParameters.pageType]; + if (requestParameters.parentPageType.length) { + BOOL isExcluded = [[MFFreebeeHandler sharedHandler] isExcludedModule:requestParameters.parentPageType]; + [[MFFreebeeHandler sharedHandler] enableFreeBeeForCurrentModule:!isExcluded]; + } - BOOL isExcluded = [[MFFreebeeHandler sharedHandler] isExcludedModule:requestParameters.parentPageType]; - [[MFFreebeeHandler sharedHandler] enableFreeBeeForCurrentModule:!isExcluded]; - - // to enable only for self server module - if(NO == isExcluded){ + if (isAllowedPage || (!isAllowedPage && [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule])) { NSDictionary* campaignDictionary = [[MFFreebeeHandler sharedHandler] campaignHeaderforUrl:request.URL]; - if(campaignDictionary) { - + if (campaignDictionary) { MVMCoreLog(@"Freebee Request Campaign Dictionary : %@", campaignDictionary); [request addValue:campaignDictionary[@"Proxy-Authorization"] forHTTPHeaderField:@"Proxy-Authorization"]; } } } - - NSError *error = nil; - NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]; - if (data) { - [request setHTTPBody:data]; + + NSError *error; + NSData *body = [self createBodyForRequestUsingParameters:parameters requestParameters:requestParameters error:&error]; + if (body) { + [request setHTTPBody:body]; } else { // Log the json error MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:nil message:nil code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"requestWithParameters_%@",requestParameters.pageType]]; @@ -222,6 +214,72 @@ return request; } +- (NSString *)boundaryForMultipartRequest { + + static NSString *boundary; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + boundary = [NSString stringWithFormat:@"MFBoundary-%@",[NSUUID UUID]]; + }); + return boundary; +} + +- (void)setHeadersForRequest:(NSMutableURLRequest *)request requestParameters:(MVMCoreRequestParameters *)requestParameters { + + [request setHTTPMethod:@"POST"]; + [request setValue:@"no-cache, no-store" forHTTPHeaderField:@"Cache-Control"]; + + // If we're uploading an image, create a multipart request, else create the normal json request + if (requestParameters.imageData) { + + NSString *boundary = [self boundaryForMultipartRequest]; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; + [request setValue:contentType forHTTPHeaderField:@"Content-Type"]; + } else { + + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; + } +} + +- (NSData *)createBodyForRequestUsingParameters:(NSDictionary *)parameters requestParameters:(MVMCoreRequestParameters *)requestParameters error:(NSError **)error { + + NSMutableData *body = [[NSMutableData alloc] init]; + + if (requestParameters.imageData) { + + NSData *imageData = requestParameters.imageData; + NSString *boundary = [self boundaryForMultipartRequest]; + [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", @"mfRequest"] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Type: application/json\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:error]; + if (jsonData) { + [body appendData:jsonData]; + } else { + return nil; + } + [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"profileImage.png\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Type: image/png\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[@"Content-Transfer-Encoding: base64\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:imageData]; + [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [body appendData:[[NSString stringWithFormat:@"--%@--", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + } else { + NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:error]; + if (data) { + [body appendData:data]; + } else { + return nil; + } + } + + return body; +} + - (nonnull NSURLSessionTask *)sendRequest:(nonnull MVMCoreRequestParameters *)requestParameters locationForError:(nonnull NSString *)locationForError requestFinished:(nullable void (^)(id _Nullable jsonObject, MVMCoreErrorObject *_Nullable error))requestFinished { #if ENABLE_HARD_CODED_RESPONSE @@ -237,17 +295,18 @@ NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]; NSURLRequest *request = [self requestWithParameters:requestParameters]; NSURLSession *session = [MVMCoreSessionObject sharedGlobal].session; - - - //In case of error for time out, we need to revert to normal session object - if(YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabled] && - YES == [[MFFreebeeHandler sharedHandler] isValidCampaign] && - YES == [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule]) { - - // to enable only for self server module - if([MVMCoreSessionObject sharedGlobal].freeBeeSession != nil) { - session = [MVMCoreSessionObject sharedGlobal].freeBeeSession; - MVMCoreLog(@"*********************************FreeBee Sponsored Request Start**********************************"); + + if ([[MFFreebeeHandler sharedHandler] isFreeBeeEnabled] + && [[MFFreebeeHandler sharedHandler] isValidCampaign]) { + BOOL isAllowedPage = [[MFFreebeeHandler sharedHandler] isAllowedPage:requestParameters.pageType]; + //In case of error for time out, we need to revert to normal session object + if (isAllowedPage || (!isAllowedPage && [[MFFreebeeHandler sharedHandler] isFreeBeeEnabledForCurrentModule])) { + + // to enable only for self server module + if ([MVMCoreSessionObject sharedGlobal].freeBeeSession) { + session = [MVMCoreSessionObject sharedGlobal].freeBeeSession; + MVMCoreLog(@"*********************************FreeBee Sponsored Request Start**********************************"); + } } } @@ -296,10 +355,13 @@ // Empty response. errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorCritical] code:ErrorCodeEmptyResponse domain:ErrorDomainNative location:locationForError]; } + } else if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(createErrorObjectForRequestNSError:forRequest:location:)]) { + + // Delegate handles the load error + errorObject = [[MVMCoreObject sharedInstance].globalLoadDelegate createErrorObjectForRequestNSError:error forRequest:request location:locationForError]; } else { - // If the request was cancelled due to SSL error or other issues. // Error with the request. - errorObject = [MFSSLPinningHandler createErrorObjectForNSErrorAndVerifySSLErrors:error location:locationForError]; + errorObject = [MVMCoreErrorObject createErrorObjectForNSError:error location:locationForError]; } if (requestFinished) { @@ -357,8 +419,4 @@ return YES; } -+ (void)defaultLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController *)loadedViewController error:(nullable MVMCoreErrorObject *)error { -// [[MFAdobeTracker sharedTracker] trackResponseInfo:loadObject.responseInfoMap forPagetype:loadObject.pageType]; -} - @end diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h index daa038f..dfe6705 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h @@ -12,7 +12,6 @@ #import #import - @class MVMCoreLoadRequestOperation; @class MVMCoreRequestParameters; diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index 2f466a9..0b530b5 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -17,9 +17,6 @@ #import "MVMCoreViewControllerMappingObject.h" #import "MVMCoreNavigationHandler.h" #import "MVMCoreAlertObject.h" -#import "MFFreebeeHandler.h" -#import "FreeBeeAuthObject.h" -#import "MFSSLPinningHandler.h" #import #import "MVMCoreLoadObject.h" #import "MVMCoreRequestParameters.h" @@ -329,7 +326,7 @@ } } -+ (void)notifyListenersOfNewResponse:(NSDictionary *)pages modules:(NSDictionary *)modules systemParameters:(NSDictionary *)systemParameters { ++ (void)notifyListenersOfNewResponse:(NSDictionary *)pages modules:(NSDictionary *)modules systemParameters:(NSDictionary *)systemParameters loadObject:(nonnull MVMCoreLoadObject *)loadObject { NSMutableDictionary *userInfo = nil; if (pages.count > 0 || modules.count > 0 || systemParameters.count > 0) { @@ -343,6 +340,9 @@ if (systemParameters.count > 0) { [userInfo setObject:systemParameters forKey:KeySystemParameters]; } + if (loadObject) { + [userInfo setObject:loadObject forKey:NSStringFromClass([MVMCoreLoadObject class])]; + } } if (userInfo) { @@ -389,7 +389,7 @@ [MVMCoreLoadRequestOperation handleShouldContinue:shouldContinue error:moduleCachingError loadObject:loadObject errorBlock:^{ // Notify of system parameters if error. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:nil systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:nil systemParameters:systemParameters loadObject:loadObject]; } continueBlock:^{ // Handle any module caching error and continue load. @@ -404,7 +404,7 @@ [MVMCoreLoadRequestOperation handleShouldContinue:shouldContinue error:pagesCachingError loadObject:loadObject errorBlock:^{ // Notify of module updates if we are erroring out. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:modules systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:nil modules:modules systemParameters:systemParameters loadObject:loadObject]; } continueBlock:^{ // Handle any page caching error and continue load. @@ -417,7 +417,7 @@ [MVMCoreLoadRequestOperation handleShouldContinue:shouldContinueLoad error:error loadObject:loadObject errorBlock:^{ // Notify of module/pages updates if we are erroring out. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject]; } continueBlock:^{ if (error) { // Hold onto any error until we establish a delegate @@ -435,7 +435,7 @@ if (loadObject.pageDataFromCache) { // Notify listeners of module/pages loaded. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject]; // Just continue if coming from cache. completionHandler(loadObject,error); @@ -447,7 +447,7 @@ }]; // Notify listeners of module/pages loaded. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pages modules:modules systemParameters:systemParameters loadObject:loadObject]; } else { NSDictionary *pagesLoaded = pages; @@ -465,7 +465,7 @@ } // Notify listeners of things loaded. - [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pagesLoaded modules:modules systemParameters:systemParameters]; + [MVMCoreLoadRequestOperation notifyListenersOfNewResponse:pagesLoaded modules:modules systemParameters:systemParameters loadObject:loadObject]; completionHandler(loadObject,error); } @@ -755,32 +755,9 @@ } // Once displyed, we are finished. - void (^completionBlock)(void) = ^{ + [MVMCoreActionUtility displayViewController:viewController forLoadObject:loadObject presentationDelegate:loadObject.operation completionHandler:^{ [MVMCoreLoadRequestOperation loadFinished:loadObject loadedViewController:viewController errorObject:error]; - }; - - // Lets the server determine the presentation style if not explicitely set by developer. - if (loadObject.requestParameters.loadStyle == MFLoadStyleDefault) { - - // Sets it first based on the action map. - NSString *presentationStyle = [loadObject.requestParameters.actionMap stringForKey:KeyPresentationStyle]; - [loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle]; - - // Let's the response override if needed. - presentationStyle = [loadObject.pageJSON stringForKey:KeyPresentationStyle]; - [loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle]; - } - - // Check if we need to load on another control - __block UIViewController *viewControllerToLoad = nil; - if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getViewManagerWithViewController:loadObject:)]) { - [MVMCoreDispatchUtility performSyncBlockOnMainThread:^{ - viewControllerToLoad = [[MVMCoreObject sharedInstance].globalLoadDelegate getViewManagerWithViewController:viewController loadObject:loadObject]; - }]; - } - - // Navigates - [[MVMCoreNavigationHandler sharedNavigationHandler] navigateWithLoadObject:loadObject viewController:(viewControllerToLoad ?: viewController) delegate:loadObject.operation completionHandler:completionBlock]; + }]; } + (void)handleError:(nonnull MVMCoreErrorObject *)error loadObject:(nonnull MVMCoreLoadObject *)loadObject showAlertForErrorIfApplicable:(BOOL)showAlertForErrorIfApplicable { @@ -856,7 +833,7 @@ if ([loadObject.delegate respondsToSelector:@selector(loadFinished:loadedViewController:error:)]) { [loadObject.delegate loadFinished:loadObject loadedViewController:loadedViewController error:errorObject]; } else { - [MVMCoreLoadHandler defaultLoadFinished:loadObject loadedViewController:loadedViewController error:errorObject]; + [MVMCoreLoggingHandler logWithDelegateLoadFinished:loadObject loadedViewController:loadedViewController error:errorObject]; } [loadObject.operation markAsFinished]; } @@ -904,5 +881,4 @@ } } - @end diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h index 157ab5d..315c521 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h @@ -31,6 +31,7 @@ typedef NS_ENUM(NSInteger, MFLoadStyle) { @property (nullable, strong, nonatomic) NSString *pageType; @property (nullable, strong, nonatomic) NSArray *modules; @property (nullable, strong, nonatomic) NSDictionary *parameters; +@property (nullable, strong, nonatomic) NSData *imageData; // adding parent pageType for freebee @property (nullable, strong, nonatomic) NSString *parentPageType; diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.m b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.m index b0d4bfe..70bb74c 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.m @@ -130,6 +130,7 @@ copyObject.allowAlertsIfBackgroundRequest = self.allowAlertsIfBackgroundRequest; copyObject.alternateBaseURL = self.alternateBaseURL; copyObject.openSupportPanel = self.openSupportPanel; + copyObject.imageData = self.imageData; return copyObject; } diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/DigiCertGlobalRootCA.cer b/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/DigiCertGlobalRootCA.cer deleted file mode 100644 index 2f1e552..0000000 Binary files a/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/DigiCertGlobalRootCA.cer and /dev/null differ diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer b/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer deleted file mode 100644 index 9818d19..0000000 Binary files a/MVMCore/MVMCore/LoadHandling/SSLPinning/Certificates/VeriSignClass3PublicPrimaryCertificationAuthority-G5.cer and /dev/null differ diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.h b/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.h deleted file mode 100644 index 041bdb8..0000000 --- a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// MFSSLPinningHandler.h -// mobilefirst -// -// Created by Pfeil, Scott Robert on 8/3/17. -// Copyright © 2017 Verizon Wireless. All rights reserved. -// - -#import - -@class MVMCoreErrorObject; -@class MVMCoreRequestParameters; -@class MFURLSessionChallengeResult; - -@interface MFSSLPinningHandler : NSObject - -#pragma mark - SSL Data - -// To setup SSL pinning status. -+ (void)setupSSLData:(NSString *_Nullable)status; - -#pragma mark NSURLSessionDelegate methods - -// Handles like the delegate function for the URLSession -+ (MFURLSessionChallengeResult * _Nonnull)getResultForURLSession:(NSURLSession *_Nonnull)session didReceiveChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge; - -#pragma mark - Error Handling - -// Creates and returns SSL error object for the NSError. -+ (nonnull MVMCoreErrorObject *)errorObjectForSSLErrors:(nullable NSString *)locationForError; - -// Creates and returns either an SSL error object or normal error object for the NSError. -+ (nonnull MVMCoreErrorObject *)createErrorObjectForNSErrorAndVerifySSLErrors:(nonnull NSError *)error location:(nullable NSString *)locationForError; - -// To invoke SSL Error Handling flow, when error code:NSURLErrorCancelled is thrown while connecting to server API's for each session. -// it is used for redirection flows -+ (void)handleSSLErrors:(nullable MVMCoreErrorObject *)errorObject requestParameters:(nonnull MVMCoreRequestParameters *)requestParameters; - -#pragma mark - SSL Logging - -// To log SSL error on MF Server -+ (void)logSSLError:(NSString *_Nonnull)tag; - -@end diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.m b/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.m deleted file mode 100644 index 8b40a39..0000000 --- a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFSSLPinningHandler.m +++ /dev/null @@ -1,585 +0,0 @@ -// -// MFSSLPinningHandler.m -// mobilefirst -// -// To handle SSL pinning: -// It will be pinning client and server root certificate/public key to secure app -// -// Created by Pfeil, Scott Robert on 8/3/17. -// Updated by Khan, Arshad on 8/23/17 -// Copyright © 2017 Verizon Wireless. All rights reserved. -// - -#import "MFSSLPinningHandler.h" -#import "MVMCoreErrorObject.h" -#import "MVMCoreRequestParameters.h" -#import "MVMCoreNavigationHandler.h" -#import "MVMCoreSessionObject.h" -#import "MVMCoreLoadHandler.h" -#import "MVMCoreLoggingHandler.h" -#import "MFURLSessionChallengeResult.h" -#import -#import "MVMCoreJSONConstants.h" -#import "MVMCoreActionUtility.h" -#import "MVMCoreGetterUtility.h" -#import "MVMCoreLoadObject.h" -#import "MVMCoreErrorConstants.h" -#import "MVMCoreHardcodedStringsConstants.h" -#import "MVMCoreObject.h" - -NSString * const MF_IOS_SSL_CERT_PATH_NOT_FOUND = @"MF_IOS_SSL_CERT_PATH_NOT_FOUND"; -NSString * const MF_IOS_SSL_CERT_PINNED = @"MF_IOS_SSL_CERT_PINNED"; -NSString * const MF_IOS_SSL_PUBLIC_KEY_PINNED = @"MF_IOS_SSL_PUBLIC_KEY_PINNED"; -NSString * const MF_IOS_SSL_CERT_MISMATCH = @"MF_IOS_SSL_CERT_MISMATCH"; -NSString * const MF_IOS_SSL_SERVER_CERT_DATA_NULL = @"MF_IOS_SSL_SERVER_CERT_DATA_NULL"; -NSString * const MF_IOS_SSL_CLIENT_CERT_NULL = @"MF_IOS_SSL_CLIENT_CERT_NULL"; -NSString * const MF_IOS_SSL_PINNING_SUCCESS = @"MF_IOS_SSL_PINNING_SUCCESS"; -NSString * const MF_IOS_SSL_PINNING_FAILED = @"MF_IOS_SSL_PINNING_FAILED"; -NSString * const MF_IOS_SSL_SERVER_CERT_NULL = @"MF_IOS_SSL_SERVER_CERT_NULL"; -NSString * const MF_IOS_SSL_PINNING_SWITCHED_OFF = @"MF_IOS_SSL_PINNING_SWITCHED_OFF"; -NSString * const MF_IOS_SSL_MANDATORY_UPGRADE_PAGE = @"MF_IOS_SSL_MANDATORY_UPGRADE_PAGE"; -NSString * const MF_IOS_SSL_ERROR_PAGE = @"MF_IOS_SSL_ERROR_PAGE"; - -@interface MFSSLPinningHandler () - -// Stores the ssl dictionary in the user defaults or removes. -+ (void)setupSSLData:(NSString *_Nullable)status; - -// The challenge on the request is allowed, get the result. -+ (MFURLSessionChallengeResult *)allowChallenge:(NSURLAuthenticationChallenge *)challenge; - -// Returns the path of the certificate. -+ (NSString *)getCertificatePath:(NSString *_Nullable)commonName; - -// To check expiry of pinned certificate -// we can use SecTrustSetVerifyDate as well, if below function gives any problem in future -+ (BOOL)isCertificateExpiredAtPath:(NSString*)path; - -@end - -@implementation MFSSLPinningHandler - -#pragma mark - SSL Data setup - -+ (BOOL)shouldBeSSLPinned { - NSString *hashedSslStatus = [[NSUserDefaults standardUserDefaults] stringForKey:CLIENT_SSL_STATUS_KEY]; - if (hashedSslStatus && [hashedSslStatus isEqualToString:[MVMCoreActionUtility hashStringWithSHA256:@"true"]]) { - return YES; - } else { - return NO; - } -} - -+ (void)storeSSLStatus:(NSString *_Nullable)sslStatus { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - if (sslStatus.length > 0) { - // Explicitly turning OFF SSL Pinning - [[NSUserDefaults standardUserDefaults] setObject:[MVMCoreActionUtility hashStringWithSHA256:@"false"] forKey:CLIENT_SSL_STATUS_KEY]; - } else { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:CLIENT_SSL_STATUS_KEY]; - } - }]; -} - -// Updates the ssl pinning status. -+ (void)updateSSLData:(NSString *_Nullable)sslStatus { - if (sslStatus.length>0) { - [MFSSLPinningHandler storeSSLStatus:sslStatus]; - } -} - -// Gets the ssl pinning status (if we are using or not) -+ (void)setupSSLData:(NSString *_Nullable)status { - - NSString *sslStatus = [[NSUserDefaults standardUserDefaults] stringForKey:CLIENT_SSL_STATUS_KEY]; - if (sslStatus==nil || sslStatus.length==0) { - - // None previously stored... - // By default SSL status would be true - // can be switched off from test screen - // using 'true' string for hashing and stroing this SSL status securely - sslStatus = [MVMCoreActionUtility hashStringWithSHA256:@"false"]; - // store this status for future use - [MFSSLPinningHandler storeSSLStatus:sslStatus]; - - } else if (status) { - - // Found previously stored, update. - [MFSSLPinningHandler updateSSLData:status]; - } -} - -#pragma mark- SSL Pinning functions - -BOOL evaluateCertificate(SecTrustRef secTrust) { - SecTrustResultType trustResult; - SecTrustEvaluate(secTrust, &trustResult); - BOOL isCertificateTrusted = NO; - switch (trustResult) { - case kSecTrustResultUnspecified: - case kSecTrustResultProceed: - { - isCertificateTrusted = YES; - MVMCoreLog(@"Pass: certificate is trusted"); - } - break; - case kSecTrustResultRecoverableTrustFailure: - MVMCoreLog(@"Failure: certificate is not trusted or kSecTrustResultRecoverableTrustFailure"); - default: - MVMCoreLog(@"Failure: certificate is invalid or not trustable:%u",trustResult); - break; - } - return isCertificateTrusted; -} - -SecKeyRef getPublicKeyForCertificate(SecCertificateRef clientProdCert) { - SecKeyRef aPublicKeyRef = NULL; - if (clientProdCert != NULL) { - - SecTrustRef aTrustRef = NULL; - SecPolicyRef aPolicyRef = SecPolicyCreateBasicX509(); - - if (aPolicyRef) { - if (SecTrustCreateWithCertificates((CFTypeRef)clientProdCert, aPolicyRef, &aTrustRef) == noErr) { - SecTrustResultType result; - if (aTrustRef) { - if (SecTrustEvaluate(aTrustRef, &result) == noErr) { - aPublicKeyRef = (SecKeyRef)CFBridgingRetain(CFBridgingRelease(SecTrustCopyPublicKey(aTrustRef))); - MVMCoreLog(@"Public key fetching success."); - } else { - MVMCoreLog(@"Public key fetching failed."); - } - } - } - } - if (aPolicyRef) CFRelease(aPolicyRef); - if (aTrustRef) CFRelease(aTrustRef); - } - return aPublicKeyRef; -} - -#pragma mark- SSL Pinning methods - -+ (MFURLSessionChallengeResult *)allowChallenge:(NSURLAuthenticationChallenge *)challenge { - SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; - NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; - return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential]; -} - -+ (NSString *)getCertificatePath:(NSString *_Nullable)commonName { - NSString *resourcePath = nil; - if (commonName.length>0) { - resourcePath = [commonName stringByReplacingOccurrencesOfString:@" " withString:@""]; - MVMCoreLog(@"Server Certificate Common Name: %@",commonName); - } - // prod root certificate - NSString *pathToProdCert = nil; - if (resourcePath.length>0) { - MVMCoreLog(@"Name of Certificate Resource: %@",resourcePath); - // To fetch exact certificate stored in MF bundle - // like, if digi is root certificate from server, - // then get respective certificate from local - pathToProdCert = [[MVMCoreGetterUtility bundleForMVMCore] pathForResource:resourcePath ofType:@"cer"]; - } else { - // Default is verisign - pathToProdCert = [[MVMCoreGetterUtility bundleForMVMCore] pathForResource:@"VeriSignClass3PublicPrimaryCertificationAuthority-G5" ofType:@"cer"]; - } - MVMCoreLog(@"Client Certificate Path Prod Cert: %@",pathToProdCert); - return pathToProdCert; -} - -+ (BOOL)isCertificateExpiredAtPath:(NSString *)path { - if (path) { - - // Gets the certificate and creates an object for it. - NSData *certificateData = [[NSFileManager defaultManager] contentsAtPath:path]; - SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData); - if (certificateRef != NULL) { - - // Creates a policy. - SecTrustRef trustRef = NULL; - SecPolicyRef policyRef = SecPolicyCreateBasicX509(); - if (policyRef) { - - // Creates a trust - if (SecTrustCreateWithCertificates((CFTypeRef)certificateRef, policyRef, &trustRef) == noErr) { - - // Set SSL policies for domain name check - NSMutableArray *policies = [NSMutableArray array]; - CFDataRef clientCertDataRef = (__bridge_retained CFDataRef)certificateData; - SecCertificateRef clientProdCert = SecCertificateCreateWithData(NULL, clientCertDataRef); - - CFStringRef clientHostName = SecCertificateCopySubjectSummary(clientProdCert); - - [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, clientHostName)]; - SecTrustSetPolicies(trustRef, (__bridge CFArrayRef)policies); - - // release clientHostName, because it is no logner needed - if (clientHostName) { - CFRelease(clientHostName); - } - if (clientCertDataRef) { - CFRelease(clientCertDataRef); - } - - OSStatus status = SecTrustSetVerifyDate(trustRef, (CFDateRef)[NSDate date]); - MVMCoreLog(@"Client certificate status:%d",(int)status); - if (status == errSecSuccess) { - MVMCoreLog(@"Client Certificate is not Expired"); - return NO; - } else { - MVMCoreLog(@"Client Certificate Expired"); - return YES; - } - } - } - - if (policyRef) CFRelease(policyRef); - if (trustRef) CFRelease(trustRef); - if (certificateRef) CFRelease(certificateRef); - } - return NO; - } else { - return NO; - } -} - -#pragma mark- helpers - -+ (BOOL)checkCertificatePinning:(BOOL)certificatesPinned serverPublicKey:(SecKeyRef)serverPublicKey clientPublicKey:(SecKeyRef)clientPublicKey clientProdRootCertificateData:(NSData *_Nullable)clientProdRootCertificateData serverRootCertificateData:(NSData *_Nullable)serverRootCertificateData extraInfo:(NSMutableDictionary *_Nonnull)extraInfo { - // Check equality of root certificates - if ([serverRootCertificateData isEqualToData:clientProdRootCertificateData]) { - MVMCoreLog(@"Root Certificates are equal."); - certificatesPinned = YES; -// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_PINNED]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_PINNED withExtraInfo:extraInfo]; - MVMCoreLog(@"Certificate is successfully pinned"); - } else if ( (clientPublicKey != NULL) && (serverPublicKey != NULL) && [(__bridge id)clientPublicKey isEqual:(__bridge id)serverPublicKey] ) { - // Publick key fallback flow to extend certificate pinning, even if root certificate expired. - // certificate expire fall back flow-1 - MVMCoreLog(@"public key fall back flow-1"); - certificatesPinned = YES; -// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PUBLIC_KEY_PINNED]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PUBLIC_KEY_PINNED withExtraInfo:extraInfo]; - MVMCoreLog(@"Certificate public key is successfully pinned"); - } else { - // Genuine failure case - certificatesPinned = NO; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_MISMATCH]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_MISMATCH withExtraInfo:extraInfo]; - MVMCoreLog(@"Failure Case:Client certificates data is nil or not matching with server certificate"); - } - return certificatesPinned; -} - -+ (BOOL)processClientCertificate:(BOOL)certificatesPinned extraInfo:(NSMutableDictionary *_Nonnull)extraInfo serverRootCertificateData:(NSData *_Nullable)serverRootCertificateData clientProdRootCertificateData:(NSData *_Nullable)clientProdRootCertificateData serverRootCertificate:(SecCertificateRef)serverRootCertificate serverHostNameStr:(NSString *)serverHostNameStr { - // Check, client root certificate data should not be nil - if (clientProdRootCertificateData != nil) { - // Get client certificate ref - CFDataRef clientCertDataRef = (__bridge_retained CFDataRef)clientProdRootCertificateData; - SecCertificateRef clientProdRootCert = SecCertificateCreateWithData(NULL, clientCertDataRef); - - CFStringRef clientHostName = SecCertificateCopySubjectSummary(clientProdRootCert); - NSString *clientHostNameStr = (__bridge NSString *)clientHostName; - if (clientHostNameStr) { - [extraInfo setObject:clientHostNameStr forKey:@"clientHostNameStr"]; - MVMCoreLog(@"client certificate Distinguished common Name: %@",clientHostNameStr); - } else { - MVMCoreLog(@"Failure Case:client common name is not found."); - [extraInfo setObject:@"client common name is not found" forKey:@"clientHostNameStr"]; - } - - // To log, client and server certificate's common name mismatch case - if ([serverHostNameStr isEqualToString:clientHostNameStr]) { - MVMCoreLog(@"Server Certificate is valid"); - } else { - MVMCoreLog(@"Failure Case:certificate Common name mismatch."); - [extraInfo setObject:@"certificate Common name mismatch" forKey:@"commonNameMismatch"]; - } - - // release clientHostName, because it is no logner needed - if (clientHostName) { - CFRelease(clientHostName); - } - // release clientCertDataRef, because it is no logner needed - if (clientCertDataRef) { - CFRelease(clientCertDataRef); - } - - // Get client root certificate public key. - // To extend certificate pinning, even if root certificate expired. - SecKeyRef clientPublicKey = (__bridge_retained SecKeyRef)(CFBridgingRelease(getPublicKeyForCertificate(clientProdRootCert))); - // To log, if public key is null - if (!clientPublicKey) { - MVMCoreLog(@"Failure Case:client public key is null."); - [extraInfo setObject:@"client public key is null" forKey:@"clientPublicKey"]; - } - // Get server root certificate public key. - SecKeyRef serverPublicKey = (__bridge_retained SecKeyRef)(CFBridgingRelease(getPublicKeyForCertificate(serverRootCertificate))); - // To log, if public key is null - if (!serverPublicKey) { - MVMCoreLog(@"Failure Case:server public key is null."); - [extraInfo setObject:@"server public key is null" forKey:@"serverPublicKey"]; - } - - // Check, server root certificate data should not be nil - if (serverRootCertificateData) { - certificatesPinned = [MFSSLPinningHandler checkCertificatePinning:certificatesPinned serverPublicKey:serverPublicKey clientPublicKey:clientPublicKey clientProdRootCertificateData:clientProdRootCertificateData serverRootCertificateData:serverRootCertificateData extraInfo:extraInfo]; - } else { - // Server Certificate Data is nil, this would not happen. - // But if happens then it is client side issue. So, bypass SSL Pinning - certificatesPinned = YES; - MVMCoreLog(@"Failure Case:Server Certificate Data is nil."); - [extraInfo setObject:@"serverCertificateData null" forKey:@"serverCertificateData"]; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_SERVER_CERT_DATA_NULL]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_SERVER_CERT_DATA_NULL withExtraInfo:extraInfo]; - } - // Release clientPublicKey, because it is no logner needed - if (clientPublicKey) { - CFRelease(clientPublicKey); - } - // Release serverPublicKey, because it is no logner needed - if (serverPublicKey) { - CFRelease(serverPublicKey); - } - } else { - // Client certificate data is nil, this would not happen - MVMCoreLog(@"Failure Case:Client certificate data is nil."); - [extraInfo setObject:@"clientProdCertificateData null" forKey:@"clientProdCertificateData"]; - // But if happens then it is client side issue. - // So, bypass SSL Pinning. Developer need to fix this. - // It should not block user. - certificatesPinned = YES; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_CLIENT_CERT_NULL]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CLIENT_CERT_NULL withExtraInfo:extraInfo]; - } - return certificatesPinned; -} - -+ (void)checkSSLTesting:(BOOL *)isServerCertificateTrusted withCertificatesPinned:(BOOL *)isCertificatesPinned { - // For testing, SSL error scenario - if ([[MVMCoreSessionObject sharedGlobal] testingSSLError] || [[MVMCoreSessionObject sharedGlobal] sslCertificateExpired]) { - MVMCoreLog(@"SSL Pinning Testing Error: certificate is not pinned explicitly, for testing SSL error scenarios."); - NSString *testCase = [[MVMCoreSessionObject sharedGlobal] testingSSLError] ? @"Test Case: SSL Error validated successfully." : @"Test Case: SSL Certificate expired validated successfully."; - MVMCoreLog(@"%@",testCase); - *isCertificatesPinned = NO; - *isServerCertificateTrusted = NO; - } -} - -+ (MFURLSessionChallengeResult * _Nonnull)processPinningStatus:(SecTrustRef)serverTrust isServerCertificateTrusted:(BOOL)isServerCertificateTrusted certificatesPinned:(BOOL)certificatesPinned extraInfo:(NSMutableDictionary *_Nonnull)extraInfo { - // The pinnning check - if (certificatesPinned && isServerCertificateTrusted) { - NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; -// [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_SUCCESS]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_SUCCESS withExtraInfo:extraInfo]; - MVMCoreLog(@"**********************SSL Pinning End: Pinning Successfully Completed******************************"); - return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential]; - } else { - [MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError = YES; - // either no connection or wrong SSL certificate. - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_FAILED]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_FAILED withExtraInfo:extraInfo]; - MVMCoreLog(@"SSL extraInfo:%@",extraInfo); - MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************"); - return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeCancelAuthenticationChallenge credential:NULL]; - } -} - -+ (NSData *)clientCertificateData:(NSMutableDictionary *_Nonnull)extraInfo withCommonName:(NSString *_Nullable)commonName { - NSData *clientProdRootCertificateData = nil; - NSString *pathToProdCert = [MFSSLPinningHandler getCertificatePath:commonName]; - if (pathToProdCert.length > 0) { - MVMCoreLog(@"Certificate path is found."); - clientProdRootCertificateData = [NSData dataWithContentsOfFile:pathToProdCert]; - // if not testing SSL expiry - if (!([MVMCoreSessionObject sharedGlobal].sslCertificateExpired)) { - // To check, if client root certificate is expired - [MVMCoreSessionObject sharedGlobal].sslCertificateExpired = [MFSSLPinningHandler isCertificateExpiredAtPath:pathToProdCert]; - [extraInfo setValue:[NSNumber numberWithBool:[MVMCoreSessionObject sharedGlobal].sslCertificateExpired] forKey:@"sslCertificateExpired"]; - } - } else { - MVMCoreLog(@"Failure Case:Not able to find client root certificate path"); - // log this failure with extra info - [extraInfo setObject:@"pathToProdCert is nil" forKey:@"pathToProdCert"]; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_CERT_PATH_NOT_FOUND]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_CERT_PATH_NOT_FOUND withExtraInfo:extraInfo]; - } - return clientProdRootCertificateData; -} - -#pragma mark- NSURLSessionDelegate methods - -+ (MFURLSessionChallengeResult * _Nonnull)getResultForURLSession:(NSURLSession *_Nonnull)session didReceiveChallenge:(NSURLAuthenticationChallenge *_Nonnull)challenge { - - MVMCoreLog(@"**********************SSL Pinning started******************************"); - NSMutableDictionary *extraInfo = [NSMutableDictionary dictionary]; - [extraInfo setObject:[[UIDevice currentDevice] systemVersion] forKey:ParameterOSVersion]; - - // SSL status will always be true until turned off from Test screen - if ([MFSSLPinningHandler shouldBeSSLPinned]) { - - // First, check authenticationMethod, it should be NSURLAuthenticationMethodServerTrust - if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { - - // Get server trust reference - SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; - - // Evaluate server trust or chain of certificates - MVMCoreLog(@"Evaluating server certificate"); - BOOL isServerCertificateTrusted = evaluateCertificate(serverTrust); - if (isServerCertificateTrusted) { - MVMCoreLog(@"Server certificate is Trusted."); - [extraInfo setObject:@"YES" forKey:@"isServerCertificateTrusted"]; - } else { - MVMCoreLog(@"Failure Case:Server certificate is not Trusted."); - [extraInfo setObject:@"NO" forKey:@"isServerCertificateTrusted"]; - } - - // Get certificate count from network - CFIndex certificateCount = 0; - if (serverTrust) { - certificateCount = SecTrustGetCertificateCount(serverTrust); - MVMCoreLog(@"serverCertificateCount:%ld",certificateCount); - [extraInfo setObject:[NSNumber numberWithLong:certificateCount] forKey:@"serverCertificateCount"]; - } else { - MVMCoreLog(@"Failure Case:serverTrust is nil."); - [extraInfo setObject:@"serverTrust is nil" forKey:@"serverTrust"]; - [extraInfo setObject:[NSNumber numberWithLong:certificateCount] forKey:@"serverCertificateCount"]; - } - - // Get server root certificate - SecCertificateRef serverRootCertificate = NULL; - // check certificate count to avoid crash - if (certificateCount>0) { - serverRootCertificate = SecTrustGetCertificateAtIndex(serverTrust, certificateCount-1); - } - - if (serverRootCertificate != NULL) { - - MVMCoreLog(@"Server Root Certificate:%@",serverRootCertificate); - // To check the validity of server certificate, that we are communicating to our designated mobile.vzw.com server - CFStringRef serverHostName = SecCertificateCopySubjectSummary(serverRootCertificate); - NSString *serverHostNameStr = (__bridge NSString *)serverHostName; - if (serverHostNameStr) { - MVMCoreLog(@"Server certificate distinguished common Name: %@",serverHostNameStr); - [extraInfo setObject:serverHostNameStr forKey:@"serverHostNameStr"]; - } else { - MVMCoreLog(@"Failure Case:server host name is nil."); - [extraInfo setObject:@"server host name is nil" forKey:@"serverHostNameStr"]; - } - - // release serverHostName, because it is no logner needed - if (serverHostName) { - CFRelease(serverHostName); - } - - // Get server root certficate data - CFDataRef serverCertificateDataRef = SecCertificateCopyData(serverRootCertificate); - NSData *serverRootCertificateData = (__bridge_transfer NSData*)serverCertificateDataRef; - - // Get/load client root certificate - NSData *clientProdRootCertificateData = [MFSSLPinningHandler clientCertificateData:extraInfo withCommonName:serverHostNameStr]; - - // To track certificate is pinned or not - BOOL certificatesPinned = NO; - - certificatesPinned = [MFSSLPinningHandler processClientCertificate:certificatesPinned extraInfo:extraInfo serverRootCertificateData:serverRootCertificateData clientProdRootCertificateData:clientProdRootCertificateData serverRootCertificate:serverRootCertificate serverHostNameStr:serverHostNameStr]; - - [MFSSLPinningHandler checkSSLTesting:&isServerCertificateTrusted withCertificatesPinned:&certificatesPinned]; - - // add extra info to analytics - [extraInfo setObject:[NSNumber numberWithBool:certificatesPinned] forKey:@"certificatesPinned"]; - [extraInfo setObject:[NSNumber numberWithBool:isServerCertificateTrusted] forKey:@"isServerCertificateTrusted"]; - - return [MFSSLPinningHandler processPinningStatus:serverTrust isServerCertificateTrusted:isServerCertificateTrusted certificatesPinned:certificatesPinned extraInfo:extraInfo]; - } else { - // this is should not happen, if happening then either client or apple bug - // server certificate is nil, track this and inform to server - // bcoz it is client/apple issue, then bypass SSL Pinning - MVMCoreLog(@"Failure: Server root certificate is null."); - [extraInfo setObject:@"server root Certificate null" forKey:@"serverCertificate"]; - NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_SERVER_CERT_NULL]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_SERVER_CERT_NULL withExtraInfo:extraInfo]; - MVMCoreLog(@"SSL extraInfo:%@",extraInfo); - MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************"); - return [MFURLSessionChallengeResult createChallengeResultWithDisposition:NSURLSessionAuthChallengeUseCredential credential:credential]; - } - } else { - // authenticationMethod is different - // FYI: NSURLAuthenticationMethodNTLM mean network issue - MVMCoreLog(@"Protection space authenticationMethod is different:%@",[[challenge protectionSpace] authenticationMethod]); - NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; - if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM]) { - disposition = NSURLSessionAuthChallengePerformDefaultHandling; - } - MVMCoreLog(@"If authentication Method is NSURLAuthenticationMethodNTLM, then it is network issue in your device, please referesh you internet and retry."); - MVMCoreLog(@"**********************SSL Pinning End: Pinning Failed******************************"); - return [MFURLSessionChallengeResult createChallengeResultWithDisposition:disposition credential:NULL]; - } - } else { - MVMCoreLog(@"SSL Pinning is switched off."); - [extraInfo setObject:@"Switched off" forKey:@"SSL_Status"]; - [MFSSLPinningHandler logSSLError:MF_IOS_SSL_PINNING_SWITCHED_OFF]; - [MVMCoreLoggingHandler logWithDelegateWithObject:(id)self withName:MF_IOS_SSL_PINNING_SWITCHED_OFF withExtraInfo:extraInfo]; - MVMCoreLog(@"SSL extraInfo:%@",extraInfo); - MVMCoreLog(@"**********************SSL Pinning End: Pinning is turned off ******************************"); - return [MFSSLPinningHandler allowChallenge:challenge]; - } -} - -#pragma mark- SSL Pinning Error Handling - -+ (nonnull MVMCoreErrorObject *)errorObjectForSSLErrors:(nullable NSString *)locationForError { - MVMCoreErrorObject *error = nil; - if ([MVMCoreSessionObject sharedGlobal].sslCertificateExpired) { - // SSL upgrade screen error object - error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_TITLE_KEY] message:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_MESSAGE_KEY] messageToLog:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_UPDATE_MESSAGE_KEY] code:ErrorCodeSSL domain:ErrorDomainNative location:locationForError]; - } else { - // SSL Error object - NSString *message = [NSString stringWithFormat:@"%@ %@ %@",[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_PREFIX_KEY],[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_TITLE_KEY],[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_MESSAGE_POSTFIX_KEY]]; - error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:message messageToLog:message code:ErrorCodeSSL domain:ErrorDomainNative location:locationForError]; - } - error.sslError = YES; - error.errorScreenError = YES; - return error; -} - -+ (nonnull MVMCoreErrorObject *)createErrorObjectForNSErrorAndVerifySSLErrors:(nonnull NSError *)error location:(nullable NSString *)locationForError { - MVMCoreErrorObject *errorObject = nil; - // If the request was cancelled due to SSL error. - if ([error code] == NSURLErrorCancelled && [MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError) { - errorObject = [MFSSLPinningHandler errorObjectForSSLErrors:locationForError]; - } else { - // Error with the request. - errorObject = [MVMCoreErrorObject createErrorObjectForNSError:error location:locationForError]; - } - return errorObject; -} - -+ (void)handleSSLErrors:(nullable MVMCoreErrorObject *)errorObject requestParameters:(nonnull MVMCoreRequestParameters *)requestParameters { - - // If the request was cancelled due to SSL error. - if (errorObject.code == NSURLErrorCancelled && [MVMCoreSessionObject sharedGlobal].connectionCancelledForSSLError) { - - // show SSL error screen's - MVMCoreErrorObject *sslError = [MFSSLPinningHandler errorObjectForSSLErrors:[[MVMCoreLoadHandler sharedGlobal] errorLocationForRequest:self pageType:requestParameters.pageType modules:[NSString stringWithFormat:@"%@",requestParameters.modules]]]; - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - UIViewController *viewController = [[MVMCoreObject sharedInstance].globalLoadDelegate getNativeScreenForRequestError:sslError requestObject:requestParameters]; - if (viewController) { - [[MVMCoreNavigationHandler sharedNavigationHandler] setViewControllers:@[viewController] navigationController:nil animated:YES delegate:nil replaceInStack:NO completionHandler:nil]; - - } - }]; - } -} - -#pragma mark - SSL Logging - -+ (void)logSSLError:(NSString *_Nonnull)tag { - MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:ERROR_SSL_TITLE] message:tag code:ErrorCodeSSL domain:ErrorDomainNative location:[[MVMCoreLoadHandler sharedGlobal] errorLocationForRequest:self pageType:@"SSL" modules:@""]]; - [MVMCoreLoggingHandler addErrorToLog:errorObject]; -} - -@end diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.h b/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.h deleted file mode 100644 index c4cba39..0000000 --- a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// MFURLSessionChallengeResult.h -// mobilefirst -// -// Created by Pfeil, Scott Robert on 8/4/17. -// Copyright © 2017 Verizon Wireless. All rights reserved. -// - -#import - -@interface MFURLSessionChallengeResult : NSObject - -@property (nonatomic) NSURLSessionAuthChallengeDisposition disposition; -@property (nonatomic, nullable, strong) NSURLCredential *credential; - -+ (instancetype _Nullable )createChallengeResultWithDisposition:(NSURLSessionAuthChallengeDisposition)disposition credential:(NSURLCredential * _Nullable)credential; - -@end diff --git a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.m b/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.m deleted file mode 100644 index f0beaee..0000000 --- a/MVMCore/MVMCore/LoadHandling/SSLPinning/MFURLSessionChallengeResult.m +++ /dev/null @@ -1,20 +0,0 @@ -// -// MFURLSessionChallengeResult.m -// mobilefirst -// -// Created by Pfeil, Scott Robert on 8/4/17. -// Copyright © 2017 Verizon Wireless. All rights reserved. -// - -#import "MFURLSessionChallengeResult.h" - -@implementation MFURLSessionChallengeResult - -+ (instancetype _Nullable )createChallengeResultWithDisposition:(NSURLSessionAuthChallengeDisposition)disposition credential:(NSURLCredential * _Nullable)credential { - MFURLSessionChallengeResult *result = [[MFURLSessionChallengeResult alloc] init]; - result.disposition = disposition; - result.credential = credential; - return result; -} - -@end diff --git a/MVMCore/MVMCore/MVMCore.h b/MVMCore/MVMCore/MVMCore.h index 41c00c2..dd07706 100644 --- a/MVMCore/MVMCore/MVMCore.h +++ b/MVMCore/MVMCore/MVMCore.h @@ -92,7 +92,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[]; // Other Handlers and Protocols #import #import -#import // Singletons #import @@ -104,6 +103,3 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[]; //Freebee #import - -//SSL -#import diff --git a/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h b/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h index 47d7a61..f00666c 100644 --- a/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h +++ b/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h @@ -32,4 +32,7 @@ // Can overwrite to set the request time out time. - (NSTimeInterval)timeOutIntervalForRequest:(nullable MVMCoreRequestParameters *)request; +// Can return an error object. ++ (nonnull MVMCoreErrorObject *)createErrorObjectForRequestNSError:(nonnull NSError *)error forRequest:(nonnull NSURLRequest *)request location:(nullable NSString *)locationForError; + @end diff --git a/MVMCore/MVMCore/MainProtocols/MVMCoreLoggingDelegateProtocol.h b/MVMCore/MVMCore/MainProtocols/MVMCoreLoggingDelegateProtocol.h index a5cacca..fc0e353 100644 --- a/MVMCore/MVMCore/MainProtocols/MVMCoreLoggingDelegateProtocol.h +++ b/MVMCore/MVMCore/MainProtocols/MVMCoreLoggingDelegateProtocol.h @@ -21,4 +21,7 @@ // Can be used to choose how to log error objects. - (void)addErrorToLog:(nonnull MVMCoreErrorObject *)errorObject; +// Log that the load has finished. +- (void)logLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController *)loadedViewController error:(nullable MVMCoreErrorObject *)error; + @end diff --git a/MVMCore/MVMCore/MainProtocols/MVMCoreViewControllerProtocol.h b/MVMCore/MVMCore/MainProtocols/MVMCoreViewControllerProtocol.h index f9899ad..641c630 100644 --- a/MVMCore/MVMCore/MainProtocols/MVMCoreViewControllerProtocol.h +++ b/MVMCore/MVMCore/MainProtocols/MVMCoreViewControllerProtocol.h @@ -16,6 +16,7 @@ @property (nonatomic) BOOL masterShouldBeAccessible; @property (nonatomic) BOOL supportShouldBeAccessible; @property (nonatomic) BOOL cartShouldBeAccessible; +@property (nonatomic) BOOL communityShouldBeAccessible; @property (nonatomic) BOOL closeButtonAccessible; @property (nullable, nonatomic, readonly) NSDictionary *closeButtonActionMap; diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h index c5263fb..535a5e1 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h @@ -129,6 +129,9 @@ - (void)addImageToCache:(nonnull UIImage *)image withName:(nonnull NSString *)imageName; - (void)addDataToCache:(nonnull NSData *)data withName:(nonnull NSString *)imageName; +// Removes image from cache if we need to update +- (void)removeImageFromCache:(nonnull NSString *)imageName; + // clears the image cache - (void)clearImageCache; diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m index 093b517..398f037 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m @@ -624,4 +624,29 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt"; }); } +- (void)removeImageFromCache:(nonnull NSString *)imageName { + + if (imageName) { + dispatch_barrier_async(self.imageCacheQueue, ^{ + + if ([imageName hasPrefix:@"http"]) { + for (NSString *key in self.imgCache.allKeys) { + NSURLComponents *components = [[NSURLComponents alloc] initWithString:key]; + if (components) { + components.fragment = nil; + components.query = nil; + NSString *urlWithoutParams = [components URL].absoluteString; + + if ([imageName isEqualToString:urlWithoutParams]) { + [self.imgCache removeObjectForKey:key]; + } + } + } + } else { + [self.imgCache removeObjectForKey:imageName]; + } + }); + } +} + @end diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.h b/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.h index b9ed6d1..48700ec 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.h +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.h @@ -8,6 +8,8 @@ #import #import +#import +#import #define MVMCoreLog(fmt, ...) \ [MVMCoreLoggingHandler logDebugMessageWithDelegate:[NSString stringWithFormat:(@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__]]; @@ -17,5 +19,6 @@ + (void)addErrorToLog:(nonnull MVMCoreErrorObject *)errorObject; + (void)logDebugMessageWithDelegate:(nullable NSString *)message; + (void)logWithDelegateWithObject:(nullable id)object withName:(nullable NSString *)name withExtraInfo:(nullable NSDictionary *)extra; ++ (void)logWithDelegateLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController *)loadedViewController error:(nullable MVMCoreErrorObject *)error; @end diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.m b/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.m index 9b6593c..3c1daf8 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.m +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreLoggingHandler.m @@ -29,4 +29,11 @@ } } ++ (void)logWithDelegateLoadFinished:(nullable MVMCoreLoadObject *)loadObject loadedViewController:(nullable UIViewController *)loadedViewController error:(nullable MVMCoreErrorObject *)error { + if ([[MVMCoreObject sharedInstance].loggingDelegate respondsToSelector:@selector(logWithDelegateLoadFinished:loadedViewController:error:)]) { + [[MVMCoreObject sharedInstance].loggingDelegate logLoadFinished:loadObject loadedViewController:loadedViewController error:error]; + } +} + + @end diff --git a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m index 9750d65..45d8647 100644 --- a/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m +++ b/MVMCore/MVMCore/PresentationHandling/MVMCoreNavigationOperation.m @@ -50,10 +50,10 @@ // Check if tab control. NSString *pageType = [self.navigationObject.viewController performSelector:@selector(pageType)]; - if ([self.navigationObject.viewController conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)]) { + if ([controller conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)] && [self.navigationObject.viewController conformsToProtocol:@protocol(MVMCoreViewManagerProtocol)]) { // Check if page is in view manager, if so, replace it. - if ([((UIViewController *)self.navigationObject.viewController) containsPageWithPageType:pageType]) { + if ([((UIViewController *)controller) containsPageWithPageType:pageType]) { location = i; break; } diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionObject.h b/MVMCore/MVMCore/Session/MVMCoreSessionObject.h index 7c9eb33..133af32 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionObject.h +++ b/MVMCore/MVMCore/Session/MVMCoreSessionObject.h @@ -22,12 +22,6 @@ // The context root to use on the base url. @property (nullable, strong, nonatomic) NSString *contextRoot; -// SSL error -@property (assign, nonatomic) BOOL sslCertificateExpired; -@property (assign, nonatomic) BOOL testingSSLError; -@property (assign, nonatomic) BOOL connectionCancelledForSSLError; -@property (assign, nonatomic) BOOL isClientPulling; - // Returns the shared instance of this singleton + (nullable instancetype)sharedGlobal; diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index 6259683..536a018 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -141,7 +141,7 @@ if (self.sessionBeingTimed || self.sessionTimedOut) { NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; - if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) { + if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (fequal(0, self.secondsUntilWarning) && !fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) { // Timeout if we are passed the warning. [[MVMCoreAlertHandler sharedAlertHandler] removeAllAlertViews]; diff --git a/MVMCore/MVMCore/Strings/en.lproj/Localizable.strings b/MVMCore/MVMCore/Strings/en.lproj/Localizable.strings index b4ce3b2..dd2d461 100644 --- a/MVMCore/MVMCore/Strings/en.lproj/Localizable.strings +++ b/MVMCore/MVMCore/Strings/en.lproj/Localizable.strings @@ -13,11 +13,3 @@ "Error Message Critical Key" = "Unable to process your request at this time. Please contact Customer Service by dialing *611. Thank you."; "Error Message Unable To Process Request Key" = "Unable to process your request. Please try again later."; -//SSL Pinning -"SSL Error Message Prefix" = "Sorry; you're unable to login to My Verizon App at this time. Please check your network connection or try again later or visit"; -"SSL Error Message Title" = "verizonwireless.com"; -"SSL Error Message Postfix" = "(SSL Cerificate Verification Failed)."; -"SSL Update Title" = "Help us keep you safe."; -"SSL Update Message" = "Update your My Verizon App to ensure it's aligned with our latest security standards."; -"SSL Error Title" = "SSL Error"; - diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.h b/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.h index 6c0a6ed..28997f8 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.h +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.h @@ -8,6 +8,9 @@ #import #import +#import +#import +#import @interface MVMCoreActionUtility : NSObject @@ -17,8 +20,8 @@ // Links away to safari or another app. Returns if successful. + (BOOL)linkAway:(nullable NSString *)safariURLString appURLString:(nullable NSString *)appURLString; -// Hashes the passed in string with SHA256. Returns the hashed string. -+ (nullable NSString *)hashStringWithSHA256:(nullable NSString *)stringToHash; +// Can call to display a view controller based on the load object in the same way the architecture does it. Will check the presentation style of the page, action, and request. Will check if needs a view manager. ++ (void)displayViewController:(nonnull UIViewController *)viewController forLoadObject:(nullable MVMCoreLoadObject *)loadObject presentationDelegate:(nullable NSObject*)delegate completionHandler:(nullable void (^)(void))completionBlock; #pragma mark - keyboard diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.m index 857d27a..7fb4f94 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreActionUtility.m @@ -9,7 +9,14 @@ #import "MVMCoreActionUtility.h" #import "MVMCoreDispatchUtility.h" #import -#import +#import "MVMCoreViewControllerProtocol.h" +#import "MVMCorePresentationDelegateProtocol.h" +#import "MVMCoreLoadObject.h" +#import "MVMCoreRequestParameters.h" +#import "NSDictionary+MFConvenience.h" +#import "MVMCoreJSONConstants.h" +#import "MVMCoreObject.h" +#import "MVMCoreNavigationHandler.h" @implementation MVMCoreActionUtility @@ -104,19 +111,30 @@ } } -+ (NSString *)hashStringWithSHA256:(NSString *)stringToHash { ++ (void)displayViewController:(nonnull UIViewController *)viewController forLoadObject:(nullable MVMCoreLoadObject *)loadObject presentationDelegate:(nullable NSObject*)delegate completionHandler:(nullable void (^)(void))completionBlock { - NSString *hashedString = nil; - if (stringToHash) { - NSData *data = [stringToHash dataUsingEncoding:NSUTF8StringEncoding]; + // Lets the server determine the presentation style if not explicitely set by developer. + if (loadObject.requestParameters.loadStyle == MFLoadStyleDefault) { - unsigned char hashedBytes[CC_SHA256_DIGEST_LENGTH]; - CC_SHA256([data bytes],(uint)[data length], hashedBytes); + // Sets it first based on the action map. + NSString *presentationStyle = [loadObject.requestParameters.actionMap stringForKey:KeyPresentationStyle]; + [loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle]; - NSData *hashedData = [NSData dataWithBytes:hashedBytes length:CC_SHA256_DIGEST_LENGTH]; - hashedString = [hashedData base64EncodedStringWithOptions:0]; + // Let's the response override if needed. + presentationStyle = [loadObject.pageJSON stringForKey:KeyPresentationStyle]; + [loadObject.requestParameters setMFLoadStyleBasedOnPresentationStyle:presentationStyle]; } - return hashedString; + + // Check if we need to load on another control + __block UIViewController *viewControllerToLoad = nil; + if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getViewManagerWithViewController:loadObject:)]) { + [MVMCoreDispatchUtility performSyncBlockOnMainThread:^{ + viewControllerToLoad = [[MVMCoreObject sharedInstance].globalLoadDelegate getViewManagerWithViewController:viewController loadObject:loadObject]; + }]; + } + + // Navigates + [[MVMCoreNavigationHandler sharedNavigationHandler] navigateWithLoadObject:loadObject viewController:(viewControllerToLoad ?: viewController) delegate:delegate completionHandler:completionBlock]; } #pragma mark - keyboard