diff options
-rwxr-xr-x | build-mac/mailcore2.xcodeproj/project.pbxproj | 44 | ||||
-rw-r--r-- | src/cmake/core.cmake | 2 | ||||
-rw-r--r-- | src/cmake/objc.cmake | 3 | ||||
-rw-r--r-- | src/cmake/public-headers.cmake | 2 | ||||
-rw-r--r-- | src/core/abstract/MCErrorMessage.cpp | 2 | ||||
-rw-r--r-- | src/core/abstract/MCMessageConstants.h | 1 | ||||
-rw-r--r-- | src/core/provider/MCAccountValidator.cpp | 425 | ||||
-rw-r--r-- | src/core/provider/MCAccountValidator.h | 107 | ||||
-rw-r--r-- | src/core/provider/MCMXRecordResolverOperation.cpp | 71 | ||||
-rw-r--r-- | src/core/provider/MCMXRecordResolverOperation.h | 41 | ||||
-rw-r--r-- | src/core/provider/MCProvider.h | 1 | ||||
-rw-r--r-- | src/objc/abstract/MCOConstants.h | 2 | ||||
-rw-r--r-- | src/objc/provider/MCOAccountValidator.h | 50 | ||||
-rw-r--r-- | src/objc/provider/MCOAccountValidator.mm | 154 | ||||
-rw-r--r-- | src/objc/provider/MCOProvider.h | 2 |
15 files changed, 906 insertions, 1 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 7e5b36b9..91c25a17 100755 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -7,11 +7,23 @@ objects = { /* Begin PBXBuildFile section */ + 2744B16A1A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2744B1681A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp */; }; + 2744B16B1A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2744B1681A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp */; }; + 27478E801A764698004AE621 /* MCAccountValidator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27478E7E1A764698004AE621 /* MCAccountValidator.cpp */; }; + 27478E811A764699004AE621 /* MCAccountValidator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27478E7E1A764698004AE621 /* MCAccountValidator.cpp */; }; + 27478E841A7646F8004AE621 /* MCOAccountValidator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27478E831A7646F8004AE621 /* MCOAccountValidator.mm */; }; + 27478E851A7646F8004AE621 /* MCOAccountValidator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27478E831A7646F8004AE621 /* MCOAccountValidator.mm */; }; + 27478E861A76475F004AE621 /* MCOAccountValidator.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 27478E821A7646F8004AE621 /* MCOAccountValidator.h */; }; + 27478E871A76475F004AE621 /* MCAccountValidator.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 27478E7F1A764698004AE621 /* MCAccountValidator.h */; }; + 27478E881A7647AC004AE621 /* MCOAccountValidator.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 27478E821A7646F8004AE621 /* MCOAccountValidator.h */; }; + 27478E891A7647AC004AE621 /* MCAccountValidator.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 27478E7F1A764698004AE621 /* MCAccountValidator.h */; }; + 276A65D01A7B7E7D008722C2 /* MCMXRecordResolverOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2744B1691A7A4637009E9E67 /* MCMXRecordResolverOperation.h */; }; 27780C2E19CF9CD100C77E44 /* MCOFramework.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6BD28A9170BDB6B00A91AC1 /* MCOFramework.mm */; }; 27780C3219CF9CD100C77E44 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6ED6D1917A1919500A4A14C /* Security.framework */; }; 27780C3619CF9CD100C77E44 /* providers.json in Resources */ = {isa = PBXBuildFile; fileRef = 84AF9E7D172DBAF600E60AA3 /* providers.json */; }; 27780C3D19CF9D9800C77E44 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27780C3C19CF9D9800C77E44 /* CFNetwork.framework */; }; 27780C3E19CF9DDF00C77E44 /* libMailCore-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C6BA2C191705F4E6003F0E9E /* libMailCore-ios.a */; }; + 27E91D601A80D3F4005A3244 /* MCMXRecordResolverOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2744B1691A7A4637009E9E67 /* MCMXRecordResolverOperation.h */; }; 4B3C1BDE17ABF309008BBF4C /* MCOIMAPQuotaOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3C1BDD17ABF307008BBF4C /* MCOIMAPQuotaOperation.mm */; }; 4B3C1BE117ABF4BC008BBF4C /* MCIMAPQuotaOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3C1BDF17ABF4BB008BBF4C /* MCIMAPQuotaOperation.cpp */; }; 4B3C1BE217ABFF7C008BBF4C /* MCOIMAPQuotaOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B3C1BDC17ABF306008BBF4C /* MCOIMAPQuotaOperation.h */; }; @@ -992,6 +1004,9 @@ dstPath = include/MailCore; dstSubfolderSpec = 16; files = ( + 27E91D601A80D3F4005A3244 /* MCMXRecordResolverOperation.h in CopyFiles */, + 27478E861A76475F004AE621 /* MCOAccountValidator.h in CopyFiles */, + 27478E871A76475F004AE621 /* MCAccountValidator.h in CopyFiles */, C673EBF01A46B45300A53F7F /* MCIMAPFolderInfo.h in CopyFiles */, C6181D3319FE0F8D0088FBBC /* MCIMAPFetchParsedContentOperation.h in CopyFiles */, C6181D3219FE0F8A0088FBBC /* MCOIMAPFetchParsedContentOperation.h in CopyFiles */, @@ -1221,6 +1236,9 @@ dstPath = include/MailCore; dstSubfolderSpec = 16; files = ( + 276A65D01A7B7E7D008722C2 /* MCMXRecordResolverOperation.h in CopyFiles */, + 27478E881A7647AC004AE621 /* MCOAccountValidator.h in CopyFiles */, + 27478E891A7647AC004AE621 /* MCAccountValidator.h in CopyFiles */, C673EBEF1A46B44E00A53F7F /* MCIMAPFolderInfo.h in CopyFiles */, 8199FBF719FAF3AF0040BBC3 /* MCOIMAPFetchParsedContentOperation.h in CopyFiles */, 8199FBF819FAF3AF0040BBC3 /* MCIMAPFetchParsedContentOperation.h in CopyFiles */, @@ -1438,6 +1456,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2744B1681A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCMXRecordResolverOperation.cpp; sourceTree = "<group>"; }; + 2744B1691A7A4637009E9E67 /* MCMXRecordResolverOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCMXRecordResolverOperation.h; sourceTree = "<group>"; }; + 27478E7E1A764698004AE621 /* MCAccountValidator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCAccountValidator.cpp; sourceTree = "<group>"; }; + 27478E7F1A764698004AE621 /* MCAccountValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCAccountValidator.h; sourceTree = "<group>"; }; + 27478E821A7646F8004AE621 /* MCOAccountValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOAccountValidator.h; sourceTree = "<group>"; }; + 27478E831A7646F8004AE621 /* MCOAccountValidator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOAccountValidator.mm; sourceTree = "<group>"; }; 27780C3A19CF9CD100C77E44 /* MailCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MailCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27780C3C19CF9D9800C77E44 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; 27780D3419CFA19500C77E44 /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/usr/lib/libstdc++.dylib"; sourceTree = DEVELOPER_DIR; }; @@ -2143,6 +2167,10 @@ 84AF9E72172DACC900E60AA3 /* provider */ = { isa = PBXGroup; children = ( + 2744B1681A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp */, + 2744B1691A7A4637009E9E67 /* MCMXRecordResolverOperation.h */, + 27478E7E1A764698004AE621 /* MCAccountValidator.cpp */, + 27478E7F1A764698004AE621 /* MCAccountValidator.h */, C6CF62BF175324F0006398B9 /* MCMailProvider.cpp */, C6CF62C0175324F0006398B9 /* MCMailProvider.h */, C6CF62C1175324F0006398B9 /* MCMailProvidersManager.cpp */, @@ -2157,6 +2185,8 @@ 84AF9E84172DBC1000E60AA3 /* provider */ = { isa = PBXGroup; children = ( + 27478E821A7646F8004AE621 /* MCOAccountValidator.h */, + 27478E831A7646F8004AE621 /* MCOAccountValidator.mm */, C6CF62B2175324CE006398B9 /* MCOMailProvider.h */, C6CF62B3175324CE006398B9 /* MCOMailProvider.mm */, C6CF62B4175324CE006398B9 /* MCOMailProvidersManager.h */, @@ -3436,6 +3466,7 @@ C68B2AF717797389005E61EF /* MCConnectionLoggerUtils.cpp in Sources */, C64EA737169E847800778456 /* MCPOPMessageInfo.cpp in Sources */, C64EA73A169E847800778456 /* MCPOPSession.cpp in Sources */, + 27478E801A764698004AE621 /* MCAccountValidator.cpp in Sources */, 84D7375C199BFDCA005124E5 /* MCNNTPListNewsgroupsOperation.cpp in Sources */, C64EA73C169E847800778456 /* MCAttachment.cpp in Sources */, C64EA73E169E847800778456 /* MCMessageBuilder.cpp in Sources */, @@ -3452,6 +3483,7 @@ C64EA7DA16A1386600778456 /* MCSMTPOperation.cpp in Sources */, C64EA7EA16A154B300778456 /* MCSMTPCheckAccountOperation.cpp in Sources */, C64EA7F116A15A4D00778456 /* MCIMAPOperation.cpp in Sources */, + 2744B16A1A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp in Sources */, BDCD7CDB1A70771B0001DCC3 /* ucln_in.cpp in Sources */, C64EA7F816A15A7800778456 /* MCIMAPCheckAccountOperation.cpp in Sources */, 943F1A9A17D964F600F0C798 /* MCIMAPConnectOperation.cpp in Sources */, @@ -3534,6 +3566,7 @@ C64BB23F16EDAAE1000DB34C /* MCOAbstractPart.mm in Sources */, C64BB24216EDAAF4000DB34C /* MCOAddress.mm in Sources */, C64BB24516EDAAFE000DB34C /* MCOMessageHeader.mm in Sources */, + 27478E841A7646F8004AE621 /* MCOAccountValidator.mm in Sources */, C64BB25216FC284A000DB34C /* NSValue+MCO.mm in Sources */, C64BB25A16FD3BCB000DB34C /* MCOOperation.mm in Sources */, C64BB25E16FD4377000DB34C /* MCOAttachment.mm in Sources */, @@ -3704,6 +3737,7 @@ C6BA2BB61705F4E6003F0E9E /* MCIMAPSession.cpp in Sources */, C68B2AF817797389005E61EF /* MCConnectionLoggerUtils.cpp in Sources */, C6BA2BB71705F4E6003F0E9E /* MCPOPMessageInfo.cpp in Sources */, + 27478E811A764699004AE621 /* MCAccountValidator.cpp in Sources */, C6BA2BB81705F4E6003F0E9E /* MCPOPSession.cpp in Sources */, 84D7375D199BFDCA005124E5 /* MCNNTPListNewsgroupsOperation.cpp in Sources */, C6BA2BB91705F4E6003F0E9E /* MCAttachment.cpp in Sources */, @@ -3720,6 +3754,7 @@ C6BA2BC01705F4E6003F0E9E /* MCSMTPSendWithDataOperation.cpp in Sources */, C6BA2BC11705F4E6003F0E9E /* MCSMTPOperation.cpp in Sources */, C6BA2BC21705F4E6003F0E9E /* MCSMTPCheckAccountOperation.cpp in Sources */, + 2744B16B1A7A4637009E9E67 /* MCMXRecordResolverOperation.cpp in Sources */, BDCD7CDC1A70771B0001DCC3 /* ucln_in.cpp in Sources */, C6BA2BC31705F4E6003F0E9E /* MCIMAPOperation.cpp in Sources */, C6BA2BC41705F4E6003F0E9E /* MCIMAPCheckAccountOperation.cpp in Sources */, @@ -3802,6 +3837,7 @@ C6BA2BF21705F4E6003F0E9E /* MCOAbstractMultipart.mm in Sources */, C6BA2BF31705F4E6003F0E9E /* MCOAbstractPart.mm in Sources */, C6BA2BF41705F4E6003F0E9E /* MCOAddress.mm in Sources */, + 27478E851A7646F8004AE621 /* MCOAccountValidator.mm in Sources */, C6BA2BF51705F4E6003F0E9E /* MCOMessageHeader.mm in Sources */, C6BA2BF61705F4E6003F0E9E /* NSValue+MCO.mm in Sources */, C6BA2BF71705F4E6003F0E9E /* MCOOperation.mm in Sources */, @@ -3958,6 +3994,7 @@ "-ltidy", "-lz", "-ObjC", + "-lresolv", ); PRODUCT_NAME = MailCore; SDKROOT = iphoneos; @@ -3985,6 +4022,7 @@ "-ltidy", "-lz", "-ObjC", + "-lresolv", ); PRODUCT_NAME = MailCore; SDKROOT = iphoneos; @@ -4028,6 +4066,7 @@ "-ObjC", "-lcrypto", "-lssl", + "-lresolv", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -4067,6 +4106,7 @@ "-ObjC", "-lcrypto", "-lssl", + "-lresolv", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -4226,6 +4266,7 @@ "-all_load", "-ltidy", "-lz", + "-lresolv", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -4257,6 +4298,7 @@ "-all_load", "-ltidy", "-lz", + "-lresolv", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -4378,6 +4420,7 @@ "-all_load", "-ltidy", "-lz", + "-lresolv", ); PRODUCT_NAME = MailCore; SDKROOT = macosx; @@ -4406,6 +4449,7 @@ "-all_load", "-ltidy", "-lz", + "-lresolv", ); PRODUCT_NAME = MailCore; SDKROOT = macosx; diff --git a/src/cmake/core.cmake b/src/cmake/core.cmake index 2f33f0d5..ac2e6ea8 100644 --- a/src/cmake/core.cmake +++ b/src/cmake/core.cmake @@ -117,6 +117,8 @@ set(provider_files core/provider/MCMailProvider.cpp core/provider/MCMailProvidersManager.cpp core/provider/MCNetService.cpp + core/provider/MCAccountValidator.cpp + core/provider/MCMXRecordResolverOperation.cpp ) set(renderer_files diff --git a/src/cmake/objc.cmake b/src/cmake/objc.cmake index f67d76e4..dfca7aee 100644 --- a/src/cmake/objc.cmake +++ b/src/cmake/objc.cmake @@ -58,6 +58,7 @@ set(objc_provider_files objc/provider/MCOMailProvider.mm objc/provider/MCOMailProvidersManager.mm objc/provider/MCONetService.mm + objc/provider/MCOAccountValidator.mm ) set(objc_rfc822_files @@ -109,6 +110,7 @@ set(objc_files ${objc_abstract_files} ${objc_imap_files} ${objc_pop_files} + ${objc_provider_files} ${objc_nntp_files} ${objc_rfc822_files} ${objc_smtp_files} @@ -123,6 +125,7 @@ set(objc_includes "${CMAKE_CURRENT_SOURCE_DIR}/objc/abstract" "${CMAKE_CURRENT_SOURCE_DIR}/objc/imap" "${CMAKE_CURRENT_SOURCE_DIR}/objc/pop" + "${CMAKE_CURRENT_SOURCE_DIR}/objc/provider" "${CMAKE_CURRENT_SOURCE_DIR}/objc/nntp" "${CMAKE_CURRENT_SOURCE_DIR}/objc/rfc822" "${CMAKE_CURRENT_SOURCE_DIR}/objc/smtp" diff --git a/src/cmake/public-headers.cmake b/src/cmake/public-headers.cmake index 40286dde..7afb5cdf 100644 --- a/src/cmake/public-headers.cmake +++ b/src/cmake/public-headers.cmake @@ -73,6 +73,7 @@ core/provider/MCProvider.h core/provider/MCMailProvidersManager.h core/provider/MCMailProvider.h core/provider/MCNetService.h +core/provider/MCAccountValidator.h async/MCAsync.h async/smtp/MCAsyncSMTP.h async/smtp/MCSMTPAsyncSession.h @@ -200,4 +201,5 @@ objc/provider/MCOProvider.h objc/provider/MCONetService.h objc/provider/MCOMailProvider.h objc/provider/MCOMailProvidersManager.h +objc/provider/MCOAccountValidator.h ) diff --git a/src/core/abstract/MCErrorMessage.cpp b/src/core/abstract/MCErrorMessage.cpp index c7205d42..15de9405 100644 --- a/src/core/abstract/MCErrorMessage.cpp +++ b/src/core/abstract/MCErrorMessage.cpp @@ -44,6 +44,8 @@ static const char * localizedDescriptionTable[] = { "A recipient is required to send message", /** MCOErrorNoRecipient */ "An error occured while performing a No-Op operation.", /** MCOErrorNoop */ "An application specific password is required", /** MCOErrorGmailApplicationSpecificPasswordRequired */ + "An error when requesting date", /** MCOErrorServerDate */ + "No valid server found", /** MCOErrorNoValidServerFound */ }; String * mailcore::errorMessageWithErrorCode(ErrorCode errorCode) diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index 1c489583..c948b7a2 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -250,6 +250,7 @@ namespace mailcore { ErrorNoop, ErrorGmailApplicationSpecificPasswordRequired, // 40 ErrorServerDate, + ErrorNoValidServerFound, }; enum PartType { diff --git a/src/core/provider/MCAccountValidator.cpp b/src/core/provider/MCAccountValidator.cpp new file mode 100644 index 00000000..8a290228 --- /dev/null +++ b/src/core/provider/MCAccountValidator.cpp @@ -0,0 +1,425 @@ +// +// MCAccountValidator.cpp +// mailcore2 +// +// Created by Christopher Hockley on 22/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#include "MCAccountValidator.h" +#include "MCMailProvider.h" +#include "MCMailProvidersManager.h" +#include "MCIMAPAsyncSession.h" +#include "MCPOPAsyncSession.h" +#include "MCSMTPAsyncSession.h" +#include "MCNetService.h" +#include "MCAddress.h" +#include "MCIMAPOperation.h" +#include "MCPOPOperation.h" +#include "MCSMTPOperation.h" +#include "MCMXRecordResolverOperation.h" + +using namespace mailcore; + +/* this is the service being tested */ + +enum { + SERVICE_IMAP, /* IMAP service */ + SERVICE_POP, /* POP service */ + SERVICE_SMTP, /* SMTP service */ +}; + +void AccountValidator::init() +{ + mEmail = NULL; + mUsername = NULL; + mPassword = NULL; + mOAuth2Token = NULL; + + mImapServices = new Array(); + mSmtpServices = new Array(); + mPopServices = new Array(); + + mIdentifier = NULL; + mImapServer = NULL; + mPopServer = NULL; + mSmtpServer = NULL; + mImapError = ErrorNone; + mPopError = ErrorNone; + mSmtpError = ErrorNone; + + mCurrentServiceIndex = 0; + mCurrentServiceTested = 0; + + mProvider = NULL; + + mOperation = NULL; + mQueue = NULL; + mResolveMX = NULL; + + mImapSession = NULL; + mPopSession = NULL; + mSmtpSession = NULL; +} + +AccountValidator::AccountValidator() +{ + init(); +} + +AccountValidator::~AccountValidator() +{ + MC_SAFE_RELEASE(mEmail); + MC_SAFE_RELEASE(mUsername); + MC_SAFE_RELEASE(mPassword); + MC_SAFE_RELEASE(mOAuth2Token); + MC_SAFE_RELEASE(mImapServices); + MC_SAFE_RELEASE(mSmtpServices); + MC_SAFE_RELEASE(mPopServices); + MC_SAFE_RELEASE(mIdentifier); + MC_SAFE_RELEASE(mProvider); + MC_SAFE_RELEASE(mOperation); + MC_SAFE_RELEASE(mQueue); + MC_SAFE_RELEASE(mResolveMX); + MC_SAFE_RELEASE(mImapSession); + MC_SAFE_RELEASE(mPopSession); + MC_SAFE_RELEASE(mSmtpSession); +} + +void AccountValidator::start() +{ + if (mEmail == NULL) { + if (mUsername == NULL) { + return; + } + else { + mEmail = mUsername; + } + } + else if (mUsername == NULL){ + mUsername = mEmail; + } + + mProvider = MailProvidersManager::sharedManager()->providerForEmail(mUsername); + + if (mProvider == NULL) { + resolveMX(); + } + else{ + startCheckingHosts(); + } +} + +void AccountValidator::cancel() +{ + if(mOperation != NULL) + mOperation->cancel(); + + if(mResolveMX != NULL) + mResolveMX->cancel(); + + if (mQueue != NULL) + mQueue->cancelAllOperations(); + + MC_SAFE_RELEASE(mOperation); + MC_SAFE_RELEASE(mResolveMX); + MC_SAFE_RELEASE(mQueue); + MC_SAFE_RELEASE(mImapSession); + MC_SAFE_RELEASE(mPopSession); + MC_SAFE_RELEASE(mSmtpSession); + + Operation::cancel(); +} + +void AccountValidator::operationFinished(Operation * op) +{ + if (op == mResolveMX) { + resolveMXDone(); + } + else { + checkNextHostDone(); + } +} + +void AccountValidator::resolveMX() +{ + Array * components; + String * domain; + + components = mUsername->componentsSeparatedByString(MCSTR("@")); + if (components->count() >= 2) { + domain = (String *) components->lastObject(); + mResolveMX = new MXRecordResolverOperation(); + mResolveMX->setHostname(domain); + mResolveMX->setCallback((OperationCallback *)this); + + mQueue = new OperationQueue(); + mQueue->addOperation(mResolveMX); + } + else { + mImapError = ErrorNoValidServerFound; + mPopError = ErrorNoValidServerFound; + mSmtpError = ErrorNoValidServerFound; + + callback()->operationFinished(this); + } +} + +void AccountValidator::resolveMXDone() +{ + Array * mxRecords = mResolveMX->mxRecords(); + + mc_foreacharray(String, mxRecord, mxRecords) { + MailProvider *provider = MailProvidersManager::sharedManager()->providerForMX(mxRecord); + if (provider){ + mProvider = provider; + break; + } + } + + startCheckingHosts(); +} + +void AccountValidator::startCheckingHosts() +{ + if (mProvider != NULL) { + mIdentifier = mProvider->identifier(); + + if (mImapServices->count() == 0 and mProvider->imapServices()->count() > 0) + mImapServices = mProvider->imapServices(); + + if (mPopServices->count() == 0 and mProvider->popServices()->count() > 0) + mPopServices = mProvider->popServices(); + + if (mSmtpServices->count() == 0 and mProvider->smtpServices()->count() > 0) + mSmtpServices = mProvider->smtpServices(); + } + + if (mImapServices->count() == 0) + mImapError = ErrorNoValidServerFound; + + if (mPopServices->count() == 0) + mPopError = ErrorNoValidServerFound; + + if (mSmtpServices->count() == 0) + mSmtpError = ErrorNoValidServerFound; + + checkNextHost(); +} + +/** + Each service(IMAP/POP/SMTP) is tested one after the other. + For each service we test each server details (NetService), + Until either: + we find on that works and returns ErrorNone in checkNextHostDone(). + we have gone trough the Array of NetService for that service and checkNextHost() is then called for the next service. + */ +void AccountValidator::checkNextHost() +{ + if (mCurrentServiceTested == SERVICE_IMAP) { + if (mCurrentServiceIndex < mImapServices->count()) { + mImapSession = new IMAPAsyncSession(); + mImapSession->setUsername(mUsername); + mImapSession->setPassword(mPassword); + + mImapServer = (NetService *) mImapServices->objectAtIndex(mCurrentServiceIndex); + mImapSession->setHostname(mImapServer->hostname()); + mImapSession->setPort(mImapServer->port()); + mImapSession->setConnectionType(mImapServer->connectionType()); + + mOperation = (IMAPOperation *)mImapSession->checkAccountOperation(); + mOperation->retain(); + mOperation->setCallback(this); + mOperation->start(); + } + else { + mCurrentServiceTested ++; + mCurrentServiceIndex = 0; + checkNextHost(); + } + } + else if (mCurrentServiceTested == SERVICE_POP){ + if (mCurrentServiceIndex < mPopServices->count()) { + mPopSession = new POPAsyncSession(); + mPopSession->setUsername(mUsername); + mPopSession->setPassword(mPassword); + + mPopServer = (NetService *) mPopServices->objectAtIndex(mCurrentServiceIndex); + mPopSession->setHostname(mPopServer->hostname()); + mPopSession->setPort(mPopServer->port()); + mPopSession->setConnectionType(mPopServer->connectionType()); + + mOperation = mPopSession->checkAccountOperation(); + mOperation->retain(); + mOperation->setCallback(this); + mOperation->start(); + } + else { + mCurrentServiceTested ++; + mCurrentServiceIndex = 0; + checkNextHost(); + } + } + else if (mCurrentServiceTested == SERVICE_SMTP){ + if (mCurrentServiceIndex < mSmtpServices->count()) { + mSmtpSession = new SMTPAsyncSession(); + mSmtpSession->setUsername(mUsername); + mSmtpSession->setPassword(mPassword); + + mSmtpServer = (NetService *) mSmtpServices->objectAtIndex(mCurrentServiceIndex); + mSmtpSession->setHostname(mSmtpServer->hostname()); + mSmtpSession->setPort(mSmtpServer->port()); + mSmtpSession->setConnectionType(mSmtpServer->connectionType()); + + mOperation = mSmtpSession->checkAccountOperation(Address::addressWithMailbox(mEmail)); + mOperation->retain(); + mOperation->setCallback(this); + mOperation->start(); + } + else { + mCurrentServiceTested ++; + mCurrentServiceIndex = 0; + checkNextHost(); + } + } + else { + callback()->operationFinished(this); + } +} + +void AccountValidator::checkNextHostDone() +{ + ErrorCode error = ErrorNone; + + if (mCurrentServiceTested == SERVICE_IMAP) { + mImapError = ((IMAPOperation *)mOperation)->error(); + error = mImapError; + MC_SAFE_RELEASE(mImapSession); + } + else if (mCurrentServiceTested == SERVICE_POP) { + mPopError = ((POPOperation *)mOperation)->error(); + error = mPopError; + MC_SAFE_RELEASE(mPopSession); + } + else if (mCurrentServiceTested == SERVICE_SMTP) { + mSmtpError = ((SMTPOperation *)mOperation)->error(); + error = mSmtpError; + MC_SAFE_RELEASE(mSmtpSession); + } + + MC_SAFE_RELEASE(mOperation); + + if (error == ErrorNone) { + mCurrentServiceTested ++; + } + else { + mCurrentServiceIndex ++; + } + + checkNextHost(); +} + +void AccountValidator::setEmail(String * email) +{ + MC_SAFE_REPLACE_COPY(String, mEmail, email); +} + +String * AccountValidator::email() +{ + return mEmail; +} + +void AccountValidator::setUsername(String * username) +{ + MC_SAFE_REPLACE_COPY(String, mUsername, username); +} + +String * AccountValidator::username() +{ + return mUsername; +} + +void AccountValidator::setPassword(String * password) +{ + MC_SAFE_REPLACE_COPY(String, mPassword, password); +} + +String * AccountValidator::password() +{ + return mPassword; +} + +void AccountValidator::setOAuth2Token(String * OAuth2Token) +{ + MC_SAFE_REPLACE_COPY(String, mOAuth2Token, OAuth2Token); +} + +String * AccountValidator::OAuth2Token() +{ + return mOAuth2Token; +} + +void AccountValidator::setImapServices(Array * imapServices) +{ + MC_SAFE_REPLACE_COPY(Array, mImapServices, imapServices); +} + +Array * AccountValidator::imapServices() +{ + return mImapServices; +} + +void AccountValidator::setSmtpServices(Array * smtpServices) +{ + MC_SAFE_REPLACE_COPY(Array, mSmtpServices, smtpServices); +} + +Array * AccountValidator::smtpServices() +{ + return mSmtpServices; +} + +void AccountValidator::setPopServices(Array * popServices) +{ + MC_SAFE_REPLACE_COPY(Array, mPopServices, popServices); +} + +Array * AccountValidator::popServices() +{ + return mPopServices; +} + +String * AccountValidator::identifier() +{ + return mIdentifier; +} + +NetService * AccountValidator::imapServer() +{ + return mImapServer; +} + +NetService * AccountValidator::smtpServer() +{ + return mSmtpServer; +} + +NetService * AccountValidator::popServer() +{ + return mPopServer; +} + +ErrorCode AccountValidator::imapError() +{ + return mImapError; +} + +ErrorCode AccountValidator::popError() +{ + return mPopError; +} + +ErrorCode AccountValidator::smtpError() +{ + return mSmtpError; +} diff --git a/src/core/provider/MCAccountValidator.h b/src/core/provider/MCAccountValidator.h new file mode 100644 index 00000000..74447ac3 --- /dev/null +++ b/src/core/provider/MCAccountValidator.h @@ -0,0 +1,107 @@ +// +// MCAccountValidator.h +// mailcore2 +// +// Created by Christopher Hockley on 22/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#ifndef MAILCORE_MCACCOUNTVALIDATOR_H + +#define MAILCORE_MCACCOUNTVALIDATOR_H + +#include <MailCore/MCBaseTypes.h> + +#ifdef __cplusplus + +namespace mailcore { + + class NetService; + class MailProvider; + class MXRecordResolverOperation; + class IMAPAsyncSession; + class POPAsyncSession; + class SMTPAsyncSession; + + class MAILCORE_EXPORT AccountValidator : public Operation, public OperationCallback { + public: + AccountValidator(); + virtual ~AccountValidator(); + + virtual void setEmail(String * email); + virtual String * email(); /* for SMTP */ + virtual void setUsername(String * username); + virtual String * username(); + virtual void setPassword(String * password); + virtual String * password(); + virtual void setOAuth2Token(String * OAuth2Token); + virtual String * OAuth2Token(); + + virtual void setImapServices(Array * imapServices); + virtual Array * /* NetService */ imapServices(); + virtual void setSmtpServices(Array * smtpServices); + virtual Array * /* NetService */ smtpServices(); + virtual void setPopServices(Array * popServices); + virtual Array * /* NetService */ popServices(); + + // result + virtual String * identifier(); + virtual NetService * imapServer(); + virtual NetService * popServer(); + virtual NetService * smtpServer(); + virtual ErrorCode imapError(); + virtual ErrorCode popError(); + virtual ErrorCode smtpError(); + + virtual void start(); + virtual void cancel(); + + private: + String * mEmail; /* for SMTP */ + String * mUsername; + String * mPassword; + String * mOAuth2Token; + + Array * /* NetService */ mImapServices; + Array * /* NetService */ mSmtpServices; + Array * /* NetService */ mPopServices; + + // result + String * mIdentifier; + NetService * mImapServer; + NetService * mPopServer; + NetService * mSmtpServer; + ErrorCode mImapError; + ErrorCode mPopError; + ErrorCode mSmtpError; + + MailProvider * mProvider; + + void resolveMX(); + void resolveMXDone(); + + void startCheckingHosts(); + void checkNextHost(); + void checkNextHostDone(); + + //indexs for services being tested + int mCurrentServiceIndex; + int mCurrentServiceTested; + + void init(); + + Operation * mOperation; + virtual void operationFinished(Operation * op); + + OperationQueue * mQueue; + MXRecordResolverOperation * mResolveMX; + + IMAPAsyncSession * mImapSession; + POPAsyncSession * mPopSession; + SMTPAsyncSession * mSmtpSession; + }; +} + +#endif + +#endif diff --git a/src/core/provider/MCMXRecordResolverOperation.cpp b/src/core/provider/MCMXRecordResolverOperation.cpp new file mode 100644 index 00000000..aa2d5448 --- /dev/null +++ b/src/core/provider/MCMXRecordResolverOperation.cpp @@ -0,0 +1,71 @@ +// +// MCFetchAsyncMXRecord.cpp +// mailcore2 +// +// Created by Christopher Hockley on 29/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#include "MCMXRecordResolverOperation.h" + +#include <arpa/inet.h> +#include <resolv.h> + +using namespace mailcore; + +MXRecordResolverOperation::MXRecordResolverOperation() +{ + mHostname = NULL; + mMXRecords = NULL; +} + +MXRecordResolverOperation::~MXRecordResolverOperation() +{ + MC_SAFE_RELEASE(mMXRecords); + MC_SAFE_RELEASE(mHostname); +} + +void MXRecordResolverOperation::setHostname(String * hostname) +{ + MC_SAFE_REPLACE_COPY(String, mHostname, hostname); +} + +String * MXRecordResolverOperation::hostname() +{ + return mHostname; +} + +Array * MXRecordResolverOperation::mxRecords() +{ + return mMXRecords; +} + +void MXRecordResolverOperation::main() +{ + mMXRecords = new Array(); + unsigned char response[NS_PACKETSZ]; + ns_msg handle; + ns_rr rr; + int len; + char dispbuf[4096]; + + if (((len = res_search(MCUTF8(mHostname), ns_c_in, ns_t_mx, response, sizeof(response))) >= 0) and + (ns_initparse(response, len, &handle) >= 0) and + (ns_msg_count(handle, ns_s_an) >= 0)) { + + for (int ns_index = 0; ns_index < len; ns_index++) { + if (ns_parserr(&handle, ns_s_an, ns_index, &rr)) { + /* WARN: ns_parserr failed */ + continue; + } + ns_sprintrr (&handle, &rr, NULL, NULL, dispbuf, sizeof (dispbuf)); + if (ns_rr_class(rr) == ns_c_in and ns_rr_type(rr) == ns_t_mx) { + char mxname[4096]; + dn_expand(ns_msg_base(handle), ns_msg_base(handle) + ns_msg_size(handle), ns_rr_rdata(rr) + NS_INT16SZ, mxname, sizeof(mxname)); + String * str = String::stringWithUTF8Characters(mxname); + mMXRecords->addObject(str); + } + } + } +} + diff --git a/src/core/provider/MCMXRecordResolverOperation.h b/src/core/provider/MCMXRecordResolverOperation.h new file mode 100644 index 00000000..7d8a6fc8 --- /dev/null +++ b/src/core/provider/MCMXRecordResolverOperation.h @@ -0,0 +1,41 @@ +// +// ResolveProviderUsingMXRecordAsync.h +// mailcore2 +// +// Created by Christopher Hockley on 29/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#ifndef MAILCORE_MCFETCHASYNCMXRECORD_H + +#define MAILCORE_MCFETCHASYNCMXRECORD_H + +#include <MailCore/MCBaseTypes.h> +#include <MailCore/MCMessageConstants.h> + +#ifdef __cplusplus + +namespace mailcore { + + class MAILCORE_EXPORT MXRecordResolverOperation : public Operation { + public: + MXRecordResolverOperation(); + virtual ~MXRecordResolverOperation(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); + + virtual Array * mxRecords(); + + public: // subclass behavior + virtual void main(); + + private: + Array * mMXRecords; + String * mHostname; + }; +} + +#endif + +#endif diff --git a/src/core/provider/MCProvider.h b/src/core/provider/MCProvider.h index b13bb263..ad8189b2 100644 --- a/src/core/provider/MCProvider.h +++ b/src/core/provider/MCProvider.h @@ -13,5 +13,6 @@ #include <MailCore/MCMailProvidersManager.h> #include <MailCore/MCMailProvider.h> #include <MailCore/MCNetService.h> +#include <MailCore/MCAccountValidator.h> #endif diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 826d047f..e4cbebef 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -409,6 +409,8 @@ typedef NS_ENUM(NSInteger, MCOErrorCode) { MCOErrorGmailApplicationSpecificPasswordRequired, // 40 /** NNTP: error when requesting date */ MCOErrorServerDate, + /** No valid server found */ + MCOErrorNoValidServerFound, /** The count of all errors */ MCOErrorCodeCount, }; diff --git a/src/objc/provider/MCOAccountValidator.h b/src/objc/provider/MCOAccountValidator.h new file mode 100644 index 00000000..0cdc25aa --- /dev/null +++ b/src/objc/provider/MCOAccountValidator.h @@ -0,0 +1,50 @@ +// +// MCOAccountValidator.h +// mailcore2 +// +// Created by Christopher Hockley on 20/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#import <Foundation/Foundation.h> +#import <MailCore/MCOOperation.h> + +/** + This class is used to validate an email provider and it's associated + metadata and credentials. + + An app might want to use this during setup to limit the number of settings + a user has to input. + */ + +@class MCONetService; + +@interface MCOAccountValidator : MCOOperation + +@property (nonatomic, copy) NSString * email; /* for SMTP */ +@property (nonatomic, copy) NSString * username; +@property (nonatomic, copy) NSString * password; +@property (nonatomic, copy) NSString * OAuth2Token; + +@property (nonatomic, retain) NSArray * /* MCONetService */ imapServers; +@property (nonatomic, retain) NSArray * /* MCONetService */ popServers; +@property (nonatomic, retain) NSArray * /* MCONetService */ smtpServers; + +// result +@property (nonatomic, retain, readonly) NSString * identifier; +@property (nonatomic, retain, readonly) MCONetService * imapServer; +@property (nonatomic, retain, readonly) MCONetService * popServer; +@property (nonatomic, retain, readonly) MCONetService * smtpServer; +@property (nonatomic, retain, readonly) NSError * imapError; +@property (nonatomic, retain, readonly) NSError * popError; +@property (nonatomic, retain, readonly) NSError * smtpError; + +/** + Starts the asynchronous account validation operation. + + @param completionBlock Called when the operation is finished. + */ +- (void) start:(void (^)(void))completionBlock; + + +@end diff --git a/src/objc/provider/MCOAccountValidator.mm b/src/objc/provider/MCOAccountValidator.mm new file mode 100644 index 00000000..b8260486 --- /dev/null +++ b/src/objc/provider/MCOAccountValidator.mm @@ -0,0 +1,154 @@ +// +// MCOAccountValidator.m +// mailcore2 +// +// Created by Christopher Hockley on 20/01/15. +// Copyright (c) 2015 MailCore. All rights reserved. +// + +#import "MCOAccountValidator.h" +#include "MCAccountValidator.h" +#include "MCNetService.h" + +#import "MCOOperation+Private.h" +#import "MCOUtils.h" +#import "MCOperationCallback.h" +#import "MCONetService.h" + +typedef void (^CompletionType)(void); + +@interface MCOAccountValidator () + +@property (nonatomic, retain) NSError * imapError; +@property (nonatomic, retain) NSError * popError; +@property (nonatomic, retain) NSError * smtpError; + +- (void) operationCompleted; + +@end + +class MCOValidatorOperationCallback: public mailcore::Object, public mailcore::OperationCallback { +public: + MCOValidatorOperationCallback(MCOAccountValidator * op) + { + mOperation = op; + } + + void operationFinished(mailcore::Operation * op) + { + [mOperation operationCompleted]; + } + +private: + MCOAccountValidator * mOperation; +}; + +@implementation MCOAccountValidator{ + CompletionType _completionBlock; + mailcore::AccountValidator * _validator; + MCOValidatorOperationCallback * _imapCallback; +} + +#define nativeType mailcore::AccountValidator + ++ (void) load +{ + MCORegisterClass(self, &typeid(nativeType)); +} + +- (mailcore::Object *) mco_mcObject +{ + return _validator; +} + ++ (NSObject *) mco_objectWithMCObject:(mailcore::Object *)object +{ + mailcore::AccountValidator * validator = (mailcore::AccountValidator *) object; + return [[[self alloc] initWithMCValidator:validator] autorelease]; +} + +MCO_OBJC_SYNTHESIZE_STRING(setEmail, email) +MCO_OBJC_SYNTHESIZE_STRING(setUsername, username) +MCO_OBJC_SYNTHESIZE_STRING(setPassword, password) +MCO_OBJC_SYNTHESIZE_STRING(setOAuth2Token, OAuth2Token) + +- (id) init +{ + mailcore::AccountValidator * validator = new mailcore::AccountValidator(); + self = [self initWithMCValidator:validator]; + validator->release(); + return self; +} + +- (id) initWithMCValidator:(mailcore::AccountValidator *)validator +{ + self = [super initWithMCOperation:validator]; + + _validator = validator; + _imapCallback = new MCOValidatorOperationCallback(self); + _validator->setCallback(_imapCallback); + _validator->retain(); + + return self; +} + +- (void) start:(void (^)(void))completionBlock +{ + _completionBlock = [completionBlock copy]; + + [self start]; +} + +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ + if (_completionBlock == NULL) + return; + + _completionBlock(); + [_completionBlock release]; + _completionBlock = nil; +} + +- (NSString *) identifier +{ + return MCO_OBJC_BRIDGE_GET(identifier); +} + +- (MCONetService *) imapServer +{ + return MCO_OBJC_BRIDGE_GET(imapServer); +} + +- (MCONetService *) popServer +{ + return MCO_OBJC_BRIDGE_GET(popServer); +} + +- (MCONetService *) smtpServer +{ + return MCO_OBJC_BRIDGE_GET(smtpServer); +} + +- (NSError *) imapError +{ + return [NSError mco_errorWithErrorCode:_validator->imapError()]; +} + +- (NSError *) popError +{ + return [NSError mco_errorWithErrorCode:_validator->popError()]; +} + +- (NSError *) smtpError +{ + return [NSError mco_errorWithErrorCode:_validator->smtpError()]; +} + +@end diff --git a/src/objc/provider/MCOProvider.h b/src/objc/provider/MCOProvider.h index 09f2cb05..3c7bf7ce 100644 --- a/src/objc/provider/MCOProvider.h +++ b/src/objc/provider/MCOProvider.h @@ -9,9 +9,9 @@ #ifndef _MAILCORE__MCOPROVIDER_h #define _MAILCORE__MCOPROVIDER_h - #import <MailCore/MCONetService.h> #import <MailCore/MCOMailProvider.h> #import <MailCore/MCOMailProvidersManager.h> +#import <MailCore/MCOAccountValidator.h> #endif |