diff options
31 files changed, 336 insertions, 81 deletions
@@ -26,14 +26,14 @@ MailCore 2 provides a simple and asynchronous Objective-C API to work with the e - Click the `+` icon and select `MailCore.framework`. * Mac static library - Go to Build Phases from your build target, and under 'Link Binary With Libraries', add `libMailCore.a` and `Security.framework`. - - Set 'Other Linker Flags' under Build Settings: `-lctemplate -letpan -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-lc++ -stdlib=libc++ -ObjC` + - Set 'Other Linker Flags' under Build Settings: `-lctemplate -letpan -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-licucore -lc++ -stdlib=libc++ -ObjC` - Make sure to use LLVM C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libc++`. - In Build Phases, add a Target Dependency of `static mailcore2 osx`. 5. **For iOS** - If you're targeting iOS, you have to link against MailCore 2 as a static library: * Add `libMailCore-ios.a` * Add `CFNetwork.framework` * Add `Security.framework` - * Set 'Other Linker Flags': `-lctemplate-ios -letpan-ios -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-lstdc++ -stdlib=libstdc++ -ObjC` + * Set 'Other Linker Flags': `-lctemplate-ios -letpan-ios -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-licucore -lstdc++ -stdlib=libstdc++ -ObjC` * Make sure to use GNU C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libstdc++`. * In Build Phases, add a Target Dependency of `static mailcore2 ios`. 6. Profit. diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 0db54b8b..0ca14ee3 100755 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -3138,6 +3138,7 @@ "-all_load", "-ltidy", "-lz", + "-licucore", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -3174,6 +3175,7 @@ "-all_load", "-ltidy", "-lz", + "-licucore", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -3239,6 +3241,7 @@ "-all_load", "-ltidy", "-lz", + "-licucore", ); PRODUCT_NAME = MailCore; SDKROOT = macosx; @@ -3271,6 +3274,7 @@ "-all_load", "-ltidy", "-lz", + "-licucore", ); PRODUCT_NAME = MailCore; SDKROOT = macosx; diff --git a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj index 37556fc4..491161bd 100644 --- a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj +++ b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj @@ -542,6 +542,7 @@ "-ltidy", "-lstdc++", "-lz", + "-licucore", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -568,6 +569,7 @@ "-ltidy", "-lstdc++", "-lz", + "-licucore", ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; diff --git a/resources/providers.json b/resources/providers.json index 7286330a..91d14182 100644 --- a/resources/providers.json +++ b/resources/providers.json @@ -66,15 +66,15 @@ } ] }, - "mx":[ - "mx1.sub3.homie.mail.dreamhost.com", - "mx2.sub3.homie.mail.dreamhost.com", - "mx1.sub4.homie.mail.dreamhost.com", - "mx2.sub4.homie.mail.dreamhost.com", - "mx1.sub5.homie.mail.dreamhost.com", - "mx2.sub5.homie.mail.dreamhost.com", - "mx1.balanced.homie.mail.dreamhost.com", - "mx2.balanced.homie.mail.dreamhost.com" + "mx-match":[ + "mx1\\.sub3\\.homie\\.mail\\.dreamhost\\.com", + "mx2\\.sub3\\.homie\\.mail\\.dreamhost\\.com", + "mx1\\.sub4\\.homie\\.mail\\.dreamhost\\.com", + "mx2\\.sub4\\.homie\\.mail\\.dreamhost\\.com", + "mx1\\.sub5\\.homie\\.mail\\.dreamhost\\.com", + "mx2\\.sub5\\.homie\\.mail\\.dreamhost\\.com", + "mx1\\.balanced\\.homie\\.mail\\.dreamhost\\.com", + "mx2\\.balanced\\.homie\\.mail\\.dreamhost\\.com" ], "mailboxes":{ "drafts":"Drafts", @@ -318,12 +318,12 @@ } ] }, - "mx":[ - "aspmx2.googlemail.com", - "aspmx.l.google.com", - "aspmx3.googlemail.com", - "alt1.aspmx.l.google.com", - "alt2.aspmx.l.google.com" + "mx-match":[ + "aspmx2\\.googlemail\\.com", + "aspmx\\.l\\.google\\.com", + "aspmx3\\.googlemail\\.com", + "alt1\\.aspmx\\.l\\.google\\.com", + "alt2\\.aspmx\\.l\\.google\\.com" ], "domain-match":[ "googlemail\\.com", @@ -634,9 +634,9 @@ } ] }, - "mx":[ - "mx1.emailsrvr.com", - "mx2.emailsrvr.com" + "mx-match":[ + "mx1\\.emailsrvr\\.com", + "mx2\\.emailsrvr\\.com" ], "mailboxes":{ "drafts":"Drafts", @@ -710,12 +710,8 @@ } ] }, - "mx":[ - "mx0.ovh.net", - "mx1.ovh.net", - "mx2.ovh.net", - "mx3.ovh.net", - "mx4.ovh.net" + "mx-match":[ + "mx\\d\\.ovh\\.net" ], "mailboxes":{ "drafts":"Drafts", @@ -769,6 +765,9 @@ } ] }, + "mx-match":[ + ".*\\.mail\\.outlook\\.com" + ], "domain-match":[ "outlook\\.com", "outlook\\.com\\.ar", @@ -865,4 +864,4 @@ "trash": "Trash" } } -}
\ No newline at end of file +} diff --git a/scripts/prepare-ctemplate-ios.sh b/scripts/prepare-ctemplate-ios.sh index 6456d532..96eda4dd 100755 --- a/scripts/prepare-ctemplate-ios.sh +++ b/scripts/prepare-ctemplate-ios.sh @@ -2,12 +2,15 @@ url="https://github.com/dinhviethoa/ctemplate" -if xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then - sdkversion=7.0 - MARCHS="armv7 armv7s arm64" +if xcodebuild -showsdks|grep iphoneos7.1 >/dev/null ; then + sdkversion=7.1 + MARCHS="armv7 armv7s arm64" +elif xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then + sdkversion=7.0 + MARCHS="armv7 armv7s arm64" elif xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then sdkversion=6.1 - MARCHS="armv7 armv7s" + MARCHS="armv7 armv7s" else echo SDK not found exit 1 diff --git a/scripts/prepare-icu4c-ios.sh b/scripts/prepare-icu4c-ios.sh index 7d42d2dd..be224d82 100755 --- a/scripts/prepare-icu4c-ios.sh +++ b/scripts/prepare-icu4c-ios.sh @@ -1,6 +1,9 @@ #!/bin/sh -if xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then +if xcodebuild -showsdks|grep iphoneos7.1 >/dev/null ; then + sdkversion=7.1 + archs="armv7 armv7s arm64 i386 x86_64" +elif xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then sdkversion=7.0 archs="armv7 armv7s arm64 i386 x86_64" elif xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then diff --git a/scripts/prepare-libetpan-ios.sh b/scripts/prepare-libetpan-ios.sh index 1495c712..8e839978 100755 --- a/scripts/prepare-libetpan-ios.sh +++ b/scripts/prepare-libetpan-ios.sh @@ -1,18 +1,21 @@ #!/bin/sh -if xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then - sdkversion=6.1 - devicearchs="armv7 armv7s" +if xcodebuild -showsdks|grep iphoneos7.1 >/dev/null ; then + sdkversion=7.1 + devicearchs="armv7 armv7s arm64" elif xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then - sdkversion=7.0 - devicearchs="armv7 armv7s arm64" + sdkversion=7.0 + devicearchs="armv7 armv7s arm64" +elif xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then + sdkversion=6.1 + devicearchs="armv7 armv7s" else echo SDK not found exit 1 fi url="https://github.com/dinhviethoa/libetpan.git" -rev=b9de519082830cfc92bceb587e8060a28735b121 +rev=f1307f3bb156b28629efe2c8339b522af58898f5 pushd `dirname $0` > /dev/null scriptpath=`pwd` diff --git a/scripts/prepare-libetpan-macos.sh b/scripts/prepare-libetpan-macos.sh index 27e3bda7..02489156 100755 --- a/scripts/prepare-libetpan-macos.sh +++ b/scripts/prepare-libetpan-macos.sh @@ -1,7 +1,7 @@ #!/bin/sh url="https://github.com/dinhviethoa/libetpan.git" -rev=b9de519082830cfc92bceb587e8060a28735b121 +rev=f1307f3bb156b28629efe2c8339b522af58898f5 pushd `dirname $0` > /dev/null scriptpath=`pwd` diff --git a/scripts/prepare-tidy-ios.sh b/scripts/prepare-tidy-ios.sh index 02aef85f..7879ffc6 100755 --- a/scripts/prepare-tidy-ios.sh +++ b/scripts/prepare-tidy-ios.sh @@ -1,11 +1,14 @@ #!/bin/sh -if xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then - sdkversion=6.1 - devicearchs="armv7 armv7s" +if xcodebuild -showsdks|grep iphoneos7.1 >/dev/null ; then + sdkversion=7.1 + devicearchs="armv7 armv7s arm64" elif xcodebuild -showsdks|grep iphoneos7.0 >/dev/null ; then sdkversion=7.0 - devicearchs="armv7 armv7s arm64" + devicearchs="armv7 armv7s arm64" +elif xcodebuild -showsdks|grep iphoneos6.1 >/dev/null ; then + sdkversion=6.1 + devicearchs="armv7 armv7s" else echo SDK not found exit 1 diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 266a120f..04d3a93c 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -552,6 +552,11 @@ unsigned int IMAPAsyncConnection::operationsCount() return mQueue->count(); } +void IMAPAsyncConnection::cancelAllOperations() +{ + mQueue->cancelAllOperations(); +} + void IMAPAsyncConnection::runOperation(IMAPOperation * operation) { if (mScheduledAutomaticDisconnect) { diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 28bac80c..6af22b50 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -167,6 +167,7 @@ namespace mailcore { virtual void runOperation(IMAPOperation * operation); virtual IMAPSession * session(); + virtual void cancelAllOperations(); virtual unsigned int operationsCount(); virtual void setLastFolder(String * folder); diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 44f753c9..c037768f 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -567,6 +567,14 @@ bool IMAPAsyncSession::isOperationQueueRunning() return mQueueRunning; } +void IMAPAsyncSession::cancelAllOperations() +{ + for(unsigned int i = 0 ; i < mSessions->count() ; i ++) { + IMAPAsyncConnection * currentSession = (IMAPAsyncConnection *) mSessions->objectAtIndex(i); + currentSession->cancelAllOperations(); + } +} + void IMAPAsyncSession::operationRunningStateChanged() { bool isRunning = false; diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index ddd672e0..b00af1d3 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -97,6 +97,7 @@ namespace mailcore { virtual void setOperationQueueCallback(OperationQueueCallback * callback); virtual OperationQueueCallback * operationQueueCallback(); virtual bool isOperationQueueRunning(); + virtual void cancelAllOperations(); virtual IMAPIdentity * serverIdentity(); virtual IMAPIdentity * clientIdentity(); diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index c2f77c89..dcc1c7cd 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -23,6 +23,7 @@ namespace mailcore { AuthTypeSASLNTLM = 1 << 6, AuthTypeSASLKerberosV4 = 1 << 7, AuthTypeXOAuth2 = 1 << 8, + AuthTypeXOAuth2Outlook = 1 << 9, }; enum IMAPFolderFlag { @@ -195,9 +196,11 @@ namespace mailcore { IMAPSearchKindSizeLarger, IMAPSearchKindSizeSmaller, IMAPSearchKindGmailThreadID, + IMAPSearchKindGmailMessageID, IMAPSearchKindGmailRaw, IMAPSearchKindOr, IMAPSearchKindAnd, + IMAPSearchKindNot, }; enum ErrorCode { diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 73b62f19..3619530b 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -49,6 +49,16 @@ void OperationQueue::addOperation(Operation * op) startThread(); } +void OperationQueue::cancelAllOperations() +{ + pthread_mutex_lock(&mLock); + for (unsigned int i = 0 ; i < mOperations->count() ; i ++) { + Operation * op = (Operation *) mOperations->objectAtIndex(i); + op->cancel(); + } + pthread_mutex_unlock(&mLock); +} + void OperationQueue::runOperationsOnThread(OperationQueue * queue) { queue->runOperations(); @@ -115,7 +125,7 @@ void OperationQueue::runOperations() if (needsCheckRunning) { retain(); // (1) - MCLog("check running %p", this); + //MCLog("check running %p", this); #if __APPLE__ performMethodOnDispatchQueue((Object::Method) &OperationQueue::checkRunningOnMainThread, this, mDispatchQueue); #else diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index 202dec40..b5f29143 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -21,6 +21,7 @@ namespace mailcore { virtual ~OperationQueue(); virtual void addOperation(Operation * op); + virtual void cancelAllOperations(); virtual unsigned int count(); diff --git a/src/core/basetypes/MCSet.cc b/src/core/basetypes/MCSet.cc index ad615388..ceccbdcc 100644 --- a/src/core/basetypes/MCSet.cc +++ b/src/core/basetypes/MCSet.cc @@ -45,7 +45,7 @@ Set * Set::setWithArray(Array * objects) String * Set::description() { String * result = String::string(); - result->appendUTF8Format("<%s:%p ", className(), this); + result->appendUTF8Format("<%s:%p ", MCUTF8(className()), this); result->appendString(mHash->allKeys()->description()); result->appendUTF8Characters(">"); return result; diff --git a/src/core/imap/MCIMAPSearchExpression.cc b/src/core/imap/MCIMAPSearchExpression.cc index 5838be00..cd3ccc2d 100644 --- a/src/core/imap/MCIMAPSearchExpression.cc +++ b/src/core/imap/MCIMAPSearchExpression.cc @@ -313,6 +313,14 @@ IMAPSearchExpression * IMAPSearchExpression::searchGmailThreadID(uint64_t number return (IMAPSearchExpression *) expr->autorelease(); } +IMAPSearchExpression * IMAPSearchExpression::searchGmailMessageID(uint64_t number) +{ + IMAPSearchExpression * expr = new IMAPSearchExpression(); + expr->mKind = IMAPSearchKindGmailMessageID; + expr->mLongNumber = number; + return (IMAPSearchExpression *) expr->autorelease(); +} + IMAPSearchExpression * IMAPSearchExpression::searchGmailRaw(String * searchExpr) { IMAPSearchExpression * expr = new IMAPSearchExpression(); @@ -339,6 +347,14 @@ IMAPSearchExpression * IMAPSearchExpression::searchOr(IMAPSearchExpression * lef return (IMAPSearchExpression *) expr->autorelease(); } +IMAPSearchExpression * IMAPSearchExpression::searchNot(IMAPSearchExpression * notExpr) +{ + IMAPSearchExpression * expr = new IMAPSearchExpression(); + expr->mKind = IMAPSearchKindNot; + MC_SAFE_REPLACE_RETAIN(IMAPSearchExpression, expr->mLeftExpression, notExpr); + return (IMAPSearchExpression *) expr->autorelease(); +} + IMAPSearchKind IMAPSearchExpression::kind() { return mKind; diff --git a/src/core/imap/MCIMAPSearchExpression.h b/src/core/imap/MCIMAPSearchExpression.h index c108fd2b..a0647216 100644 --- a/src/core/imap/MCIMAPSearchExpression.h +++ b/src/core/imap/MCIMAPSearchExpression.h @@ -54,9 +54,12 @@ namespace mailcore { static IMAPSearchExpression * searchSizeLarger(uint32_t size); static IMAPSearchExpression * searchSizeSmaller(uint32_t size); static IMAPSearchExpression * searchGmailThreadID(uint64_t number); + static IMAPSearchExpression * searchGmailMessageID(uint64_t number); static IMAPSearchExpression * searchGmailRaw(String * expr); static IMAPSearchExpression * searchAnd(IMAPSearchExpression * left, IMAPSearchExpression * right); static IMAPSearchExpression * searchOr(IMAPSearchExpression * left, IMAPSearchExpression * right); + static IMAPSearchExpression * searchNot(IMAPSearchExpression * notExpr); + public: // subclass behavior IMAPSearchExpression(IMAPSearchExpression * other); diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index faabc522..b387e48f 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -837,6 +837,7 @@ void IMAPSession::login(ErrorCode * pError) break; case AuthTypeXOAuth2: + case AuthTypeXOAuth2Outlook: r = mailimap_oauth2_authenticate(mImap, utf8username, MCUTF8(mOAuth2Token)); break; } @@ -2791,7 +2792,11 @@ static struct mailimap_search_key * searchKeyFromSearchExpression(IMAPSearchExpr case IMAPSearchKindGmailThreadID: { return mailimap_search_key_new_xgmthrid(expression->longNumber()); - } + } + case IMAPSearchKindGmailMessageID: + { + return mailimap_search_key_new_xgmmsgid(expression->longNumber()); + } case IMAPSearchKindRead: { return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SEEN, @@ -2906,6 +2911,11 @@ static struct mailimap_search_key * searchKeyFromSearchExpression(IMAPSearchExpr clist_append(list, searchKeyFromSearchExpression(expression->rightExpression())); return mailimap_search_key_new_multiple(list); } + case IMAPSearchKindNot: + { + return mailimap_search_key_new_not(searchKeyFromSearchExpression(expression->leftExpression())); + } + default: MCAssert(0); return NULL; diff --git a/src/core/provider/MCMailProvider.cc b/src/core/provider/MCMailProvider.cc index 7a8cb4cb..aec6f348 100644 --- a/src/core/provider/MCMailProvider.cc +++ b/src/core/provider/MCMailProvider.cc @@ -22,7 +22,7 @@ void MailProvider::init() mSmtpServices = new Array(); mPopServices = new Array(); mDomainMatch = new Array(); - mMxSet = new Set(); + mMxMatch = new Array(); mMailboxPaths = NULL; } @@ -39,7 +39,7 @@ MailProvider::MailProvider(MailProvider * other) MC_SAFE_REPLACE_COPY(Array, mSmtpServices, other->mSmtpServices); MC_SAFE_REPLACE_COPY(Array, mPopServices, other->mPopServices); MC_SAFE_REPLACE_COPY(Array, mDomainMatch, other->mDomainMatch); - MC_SAFE_REPLACE_COPY(Set, mMxSet, other->mMxSet); + MC_SAFE_REPLACE_COPY(Array, mMxMatch, other->mMxMatch); MC_SAFE_REPLACE_COPY(HashMap, mMailboxPaths, other->mMailboxPaths); } @@ -48,7 +48,7 @@ MailProvider::~MailProvider() MC_SAFE_RELEASE(mImapServices); MC_SAFE_RELEASE(mSmtpServices); MC_SAFE_RELEASE(mPopServices); - MC_SAFE_RELEASE(mMxSet); + MC_SAFE_RELEASE(mMxMatch); MC_SAFE_RELEASE(mDomainMatch); MC_SAFE_RELEASE(mMailboxPaths); MC_SAFE_RELEASE(mIdentifier); @@ -68,7 +68,6 @@ void MailProvider::fillWithInfo(HashMap * info) Array * smtpInfos; Array * popInfos; HashMap * serverInfo; - Array * mxs; MC_SAFE_RELEASE(mDomainMatch); if (info->objectForKey(MCSTR("domain-match")) != NULL) { @@ -78,10 +77,9 @@ void MailProvider::fillWithInfo(HashMap * info) if (info->objectForKey(MCSTR("mailboxes")) != NULL) { mMailboxPaths = (HashMap *) info->objectForKey(MCSTR("mailboxes"))->retain(); } - mxs = (Array *) info->objectForKey(MCSTR("mx")); - mMxSet->removeAllObjects(); - mc_foreacharray(String, mx, mxs) { - mMxSet->addObject(mx->lowercaseString()); + MC_SAFE_RELEASE(mMxMatch); + if (info->objectForKey(MCSTR("mx-match")) != NULL) { + mMxMatch = (Array *) info->objectForKey(MCSTR("mx-match"))->retain(); } serverInfo = (HashMap *) info->objectForKey(MCSTR("servers")); @@ -148,25 +146,11 @@ bool MailProvider::matchEmail(String * email) return false; domain = (String *) components->lastObject(); - cDomain = domain->UTF8Characters(); - + mc_foreacharray(String, match, mDomainMatch) { - regex_t r; - bool matched; - - match = String::stringWithUTF8Format("^%s$", match->UTF8Characters()); - if (regcomp(&r, match->UTF8Characters(), REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) - continue; - - matched = false; - if (regexec(&r, cDomain, 0, NULL, 0) == 0) { - matched = true; - } - - regfree(&r); - - if (matched) + if (matchDomain(match, domain)){ return true; + } } return false; @@ -174,7 +158,36 @@ bool MailProvider::matchEmail(String * email) bool MailProvider::matchMX(String * hostname) { - return mMxSet->containsObject(hostname->lowercaseString()); + mc_foreacharray(String, match, mMxMatch) { + if (matchDomain(match, hostname)){ + return true; + } + } + + return false; +} + +bool MailProvider::matchDomain(String * match, String * domain) +{ + const char * cDomain; + regex_t r; + bool matched; + + cDomain = domain->UTF8Characters(); + match = String::stringWithUTF8Format("^%s$", match->UTF8Characters()); + matched = false; + + if (regcomp(&r, match->UTF8Characters(), REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0){ + return matched; + } + + if (regexec(&r, cDomain, 0, NULL, 0) == 0) { + matched = true; + } + + regfree(&r); + + return matched; } String * MailProvider::sentMailFolderPath() @@ -232,7 +245,7 @@ bool MailProvider::isMainFolder(String * folderPath, String * prefix) } String * MailProvider::description() -{ +{ return String::stringWithUTF8Format("<%s:%p, %s>", className()->UTF8Characters(), this, MCUTF8(mIdentifier)); } diff --git a/src/core/provider/MCMailProvider.h b/src/core/provider/MCMailProvider.h index 026482b3..29ab4fa6 100644 --- a/src/core/provider/MCMailProvider.h +++ b/src/core/provider/MCMailProvider.h @@ -57,12 +57,13 @@ namespace mailcore { private: String * mIdentifier; Array * /* String */ mDomainMatch; + Array * /* String */ mMxMatch; Array * /* NetService */ mImapServices; Array * /* NetService */ mSmtpServices; Array * /* NetService */ mPopServices; HashMap * mMailboxPaths; - Set * mMxSet; + virtual bool matchDomain(String * match, String * domain); void init(); }; @@ -70,4 +71,4 @@ namespace mailcore { #endif -#endif
\ No newline at end of file +#endif diff --git a/src/core/security/MCCertificateUtils.cc b/src/core/security/MCCertificateUtils.cc index 00f4ed9e..e6e46cbf 100644 --- a/src/core/security/MCCertificateUtils.cc +++ b/src/core/security/MCCertificateUtils.cc @@ -11,6 +11,12 @@ #if __APPLE__ #include <CoreFoundation/CoreFoundation.h> #include <Security/Security.h> +#else +#include <openssl/bio.h> +#include <openssl/x509.h> +#include <openssl/x509_vfy.h> +#include <openssl/pem.h> +#include <openssl/err.h> #endif #include "MCLog.h" @@ -78,8 +84,70 @@ free_certs: err: return result; #else - //TODO check certificate - // for other platforms too. - return true; + bool result = false; + X509_STORE * store = NULL; + X509_STORE_CTX * storectx = NULL; + STACK_OF(X509) * certificates = NULL; + int status; + + carray * cCerts = mailstream_get_certificate_chain(stream); + if (cCerts == NULL) { + fprintf(stderr, "warning: No certificate chain retrieved"); + goto err; + } + + store = X509_STORE_new(); + if (store == NULL) { + goto free_certs; + } + + status = X509_STORE_set_default_paths(store); + if (status != 1) { + printf("Error loading the system-wide CA certificates"); + } + + certificates = sk_X509_new_null(); + for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { + MMAPString * str; + str = (MMAPString *) carray_get(cCerts, i); + if (str == NULL) { + goto free_certs; + } + BIO *bio = BIO_new_mem_buf((void *) str->str, str->len); + X509 *certificate = d2i_X509_bio(bio, NULL); + BIO_free(bio); + if (!sk_X509_push(certificates, certificate)) { + goto free_certs; + } + } + + storectx = X509_STORE_CTX_new(); + if (storectx == NULL) { + goto free_certs; + } + + status = X509_STORE_CTX_init(storectx, store, sk_X509_value(certificates, 0), certificates); + if (status != 1) { + goto free_certs; + } + + status = X509_verify_cert(storectx); + if (status == 1) { + result = true; + } + +free_certs: + mailstream_certificate_chain_free(cCerts); + if (certificates != NULL) { + sk_X509_pop_free((STACK_OF(X509) *) certificates, X509_free); + } + if (storectx != NULL) { + X509_STORE_CTX_free(storectx); + } + if (store != NULL) { + X509_STORE_free(store); + } +err: + return result; #endif } diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index b9f71cb9..c6f28ff9 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -400,7 +400,8 @@ void SMTPSession::login(ErrorCode * pError) { int r; - if ((authType() != AuthTypeXOAuth2) && ((username() == NULL) || (password() == NULL))) { + if ((authType() != AuthTypeXOAuth2) && (authType() != AuthTypeXOAuth2Outlook) && + ((username() == NULL) || (password() == NULL))) { mState = STATE_LOGGEDIN; * pError = ErrorNone; return; @@ -525,6 +526,15 @@ void SMTPSession::login(ErrorCode * pError) r = mailsmtp_oauth2_authenticate(mSmtp, utf8Username, MCUTF8(mOAuth2Token)); break; } + + case AuthTypeXOAuth2Outlook: { + const char * utf8Username = MCUTF8(mUsername); + if (utf8Username == NULL) { + utf8Username = ""; + } + r = mailsmtp_oauth2_outlook_authenticate(mSmtp, utf8Username, MCUTF8(mOAuth2Token)); + break; + } } if (r == MAILSMTP_ERROR_STREAM) { * pError = ErrorConnection; diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 6b6407c0..eb276e0f 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -35,6 +35,8 @@ typedef enum { MCOAuthTypeSASLKerberosV4 = 1 << 7, /** OAuth2 authentication.*/ MCOAuthTypeXOAuth2 = 1 << 8, + /** OAuth2 authentication on outlook.com.*/ + MCOAuthTypeXOAuth2Outlook = 1 << 9, } MCOAuthType; /** It's the IMAP flags of the folder.*/ @@ -184,12 +186,54 @@ typedef enum { MCOIMAPSearchKindUids, /** Match headers of the message.*/ MCOIMAPSearchKindHeader, + /** Match messages that are read.*/ + MCOIMAPSearchKindRead, + /** Match messages that are not read.*/ + MCOIMAPSearchKindUnread, + /** Match messages that are flagged.*/ + MCOIMAPSearchKindFlagged, + /** Match messages that are not flagged.*/ + MCOIMAPSearchKindUnflagged, + /** Match messages that are answered.*/ + MCOIMAPSearchKindAnswered, + /** Match messages that are not answered.*/ + MCOIMAPSearchKindUnanswered, + /** Match messages that are a drafts.*/ + MCOIMAPSearchKindDraft, + /** Match messages that are not drafts.*/ + MCOIMAPSearchKindUndraft, + /** Match messages that are deleted.*/ + MCOIMAPSearchKindDeleted, + /** Match messages that are spam.*/ + MCOIMAPSearchKindSpam, + /** Match messages before the given date.*/ + MCOIMAPSearchKindBeforeDate, + /** Match messages on the given date.*/ + MCOIMAPSearchKindOnDate, + /** Match messages after the given date.*/ + MCOIMAPSearchKindSinceDate, + /** Match messages before the given received date.*/ + MCOIMAPSearchKindBeforeReceivedDate, + /** Match messages on the given received date.*/ + MCOIMAPSearchKindOnReceivedDate, + /** Match messages after the given received date.*/ + MCOIMAPSearchKindSinceReceivedDate, + /** Match messages that are larger than the given size in bytes.*/ + MCOIMAPSearchKindSizeLarger, + /** Match messages that are smaller than the given size in bytes.*/ + MCOIMAPSearchKindSizeSmaller, /** Match X-GM-THRID.*/ MCOIMAPSearchGmailThreadID, + /** Match X-GM-MSGID.*/ + MCOIMAPSearchGmailMessageID, + /** Match X-GM-RAW.*/ + MCOIMAPSearchGmailRaw, /** Or expresssion.*/ MCOIMAPSearchKindOr, /** And expression.*/ MCOIMAPSearchKindAnd, + /** Not expression.*/ + MCOIMAPSearchKindNot, } MCOIMAPSearchKind; /** Keys for the namespace dictionary.*/ diff --git a/src/objc/imap/MCOIMAPSearchExpression.h b/src/objc/imap/MCOIMAPSearchExpression.h index d1d2d701..fbffb8f3 100644 --- a/src/objc/imap/MCOIMAPSearchExpression.h +++ b/src/objc/imap/MCOIMAPSearchExpression.h @@ -287,6 +287,16 @@ */ + (MCOIMAPSearchExpression *) searchGmailThreadID:(uint64_t)number; + +/** + Creates a search expression that matches emails with the given gmail message id + + Example: + + MCOIMAPSearchExpression * expr = [MCOIMAPSearchExpression searchGmailMessageID:aMessageID] + */ ++ (MCOIMAPSearchExpression *) searchGmailMessageID:(uint64_t)number; + /** Creates a search expression that gets emails that match a gmail raw search expression. @@ -320,6 +330,18 @@ */ + (MCOIMAPSearchExpression *) searchOr:(MCOIMAPSearchExpression *)expression other:(MCOIMAPSearchExpression *)other; +/** + Creates a search expression that matches when the argument is not matched. + + Example: + + MCOIMAPSearchExpression * exprSubject = [MCOIMAPSearchExpression searchSubject:@"airline"] + MCOIMAPSearchExpression * expr = [MCOIMAPSearchExpression searchNot:exprSubject]; + The expression will match when the subject does not contain the word airline + + */ ++ (MCOIMAPSearchExpression *) searchNot:(MCOIMAPSearchExpression *)expression; + @end #endif diff --git a/src/objc/imap/MCOIMAPSearchExpression.mm b/src/objc/imap/MCOIMAPSearchExpression.mm index a6c89e8d..f395596c 100644 --- a/src/objc/imap/MCOIMAPSearchExpression.mm +++ b/src/objc/imap/MCOIMAPSearchExpression.mm @@ -200,6 +200,11 @@ return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchGmailThreadID(number)); } ++ (MCOIMAPSearchExpression *) searchGmailMessageID:(uint64_t)number +{ + return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchGmailMessageID(number)); +} + + (MCOIMAPSearchExpression *) searchGmailRaw:(NSString *)expr { return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchGmailRaw([expr mco_mcString])); @@ -217,4 +222,10 @@ return MCO_TO_OBJC(result); } ++ (MCOIMAPSearchExpression *) searchNot:(MCOIMAPSearchExpression *)expression +{ + mailcore::IMAPSearchExpression * result = mailcore::IMAPSearchExpression::searchNot(expression->_nativeExpr); + return MCO_TO_OBJC(result); +} + @end diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 9edffa72..09f1c610 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -138,6 +138,11 @@ */ @property (nonatomic, copy) MCOOperationQueueRunningChangeBlock operationQueueRunningChangeBlock; +/** + Cancel all operations + */ +- (void) cancelAllOperations; + /** @name Folder Operations */ /** @@ -411,6 +416,7 @@ }]; @warn *Important*: This is only for servers that support Conditional Store. See [RFC4551](http://tools.ietf.org/html/rfc4551) +vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162](http://tools.ietf.org/html/rfc5162) */ - (MCOIMAPFetchMessagesOperation *) syncMessagesByUIDWithFolder:(NSString *)folder requestKind:(MCOIMAPMessagesRequestKind)requestKind diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index 0b0c638a..dddb27fa 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -168,6 +168,11 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return _operationQueueRunningChangeBlock; } +- (void) cancelAllOperations +{ + MCO_NATIVE_INSTANCE->cancelAllOperations(); +} + #pragma mark - Operations #define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op]; diff --git a/src/objc/pop/MCOPOP.h b/src/objc/pop/MCOPOP.h index 18074305..5a75ff4f 100644 --- a/src/objc/pop/MCOPOP.h +++ b/src/objc/pop/MCOPOP.h @@ -6,7 +6,7 @@ // Copyright (c) 2013 MailCore. All rights reserved. // -#ifndef MAILCORE_MCOPOP_H_ +#ifndef MAILCORE_MCOPOP_H #define MAILCORE_MCOPOP_H diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index b6ae6a4f..17dc5057 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -124,7 +124,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return result; } -- (MCOOperation *) checkAccountOperationWithFrom:(MCOAddress *)from +- (MCOSMTPOperation *) checkAccountOperationWithFrom:(MCOAddress *)from { mailcore::SMTPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(MCO_FROM_OBJC(mailcore::Address, from)); MCOSMTPOperation * result = [[[MCOSMTPOperation alloc] initWithMCOperation:coreOp] autorelease]; |