aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbuild-mac/mailcore2.xcodeproj/project.pbxproj44
-rw-r--r--src/cmake/core.cmake2
-rw-r--r--src/cmake/objc.cmake3
-rw-r--r--src/cmake/public-headers.cmake2
-rw-r--r--src/core/abstract/MCErrorMessage.cpp2
-rw-r--r--src/core/abstract/MCMessageConstants.h1
-rw-r--r--src/core/provider/MCAccountValidator.cpp425
-rw-r--r--src/core/provider/MCAccountValidator.h107
-rw-r--r--src/core/provider/MCMXRecordResolverOperation.cpp71
-rw-r--r--src/core/provider/MCMXRecordResolverOperation.h41
-rw-r--r--src/core/provider/MCProvider.h1
-rw-r--r--src/objc/abstract/MCOConstants.h2
-rw-r--r--src/objc/provider/MCOAccountValidator.h50
-rw-r--r--src/objc/provider/MCOAccountValidator.mm154
-rw-r--r--src/objc/provider/MCOProvider.h2
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