diff options
Diffstat (limited to 'src/core/pop')
-rw-r--r-- | src/core/pop/.DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | src/core/pop/MCPOP.h | 9 | ||||
-rw-r--r-- | src/core/pop/MCPOPMessageInfo.cc | 76 | ||||
-rw-r--r-- | src/core/pop/MCPOPMessageInfo.h | 38 | ||||
-rw-r--r-- | src/core/pop/MCPOPProgressCallback.h | 15 | ||||
-rw-r--r-- | src/core/pop/MCPOPSession.cc | 545 | ||||
-rw-r--r-- | src/core/pop/MCPOPSession.h | 90 |
7 files changed, 773 insertions, 0 deletions
diff --git a/src/core/pop/.DS_Store b/src/core/pop/.DS_Store Binary files differnew file mode 100644 index 00000000..5008ddfc --- /dev/null +++ b/src/core/pop/.DS_Store diff --git a/src/core/pop/MCPOP.h b/src/core/pop/MCPOP.h new file mode 100644 index 00000000..7651f9e6 --- /dev/null +++ b/src/core/pop/MCPOP.h @@ -0,0 +1,9 @@ +#ifndef __MAILCORE_MCPOP_H + +#define __MAILCORE_MCPOP_H + +#include <mailcore/MCPOPMessageInfo.h> +#include <mailcore/MCPOPProgressCallback.h> +#include <mailcore/MCPOPSession.h> + +#endif diff --git a/src/core/pop/MCPOPMessageInfo.cc b/src/core/pop/MCPOPMessageInfo.cc new file mode 100644 index 00000000..eafbda9f --- /dev/null +++ b/src/core/pop/MCPOPMessageInfo.cc @@ -0,0 +1,76 @@ +#include "MCPOPMessageInfo.h" + +using namespace mailcore; + +void POPMessageInfo::init() +{ + mIndex = 0; + mSize = 0; + mUid = NULL; +} + +POPMessageInfo::POPMessageInfo() +{ + init(); +} + +POPMessageInfo::POPMessageInfo(POPMessageInfo * other) +{ + init(); + mIndex = other->mIndex; + mSize = other->mSize; + MC_SAFE_REPLACE_COPY(String, mUid, other->mUid); +} + +POPMessageInfo::~POPMessageInfo() +{ + MC_SAFE_RELEASE(mUid); +} + +#if 0 +String * POPMessageInfo::className() +{ + return MCSTR("POPMessageInfo"); +} +#endif + +String * POPMessageInfo::description() +{ + return String::stringWithUTF8Format("<%s:%p %u %s %u>", + MCUTF8(className()), this, mIndex, MCUTF8(mUid), mSize); +} + +Object * POPMessageInfo::copy() +{ + return new POPMessageInfo(this); +} + +void POPMessageInfo::setIndex(unsigned int index) +{ + mIndex = index; +} + +unsigned int POPMessageInfo::index() +{ + return mIndex; +} + +void POPMessageInfo::setSize(unsigned int size) +{ + mSize = size; +} + +unsigned int POPMessageInfo::size() +{ + return mSize; +} + +void POPMessageInfo::setUid(String * uid) +{ + MC_SAFE_REPLACE_COPY(String, mUid, uid); +} + +String * POPMessageInfo::uid() +{ + return mUid; +} diff --git a/src/core/pop/MCPOPMessageInfo.h b/src/core/pop/MCPOPMessageInfo.h new file mode 100644 index 00000000..1e52b695 --- /dev/null +++ b/src/core/pop/MCPOPMessageInfo.h @@ -0,0 +1,38 @@ +#ifndef __MAILCORE_MCPOPMESSAGEINFO_H_ + +#define __MAILCORE_MCPOPMESSAGEINFO_H_ + +#include <mailcore/MCBaseTypes.h> + +namespace mailcore { + + class POPMessageInfo : public Object { + private: + unsigned int mIndex; + unsigned int mSize; + String * mUid; + + void init(); + + public: + POPMessageInfo(); + POPMessageInfo(POPMessageInfo * other); + virtual ~POPMessageInfo(); + + //virtual String * className(); + virtual String * description(); + virtual Object * copy(); + + virtual void setIndex(unsigned int index); + virtual unsigned int index(); + + virtual void setSize(unsigned int size); + virtual unsigned int size(); + + virtual void setUid(String * uid); + virtual String * uid(); + }; + +} + +#endif diff --git a/src/core/pop/MCPOPProgressCallback.h b/src/core/pop/MCPOPProgressCallback.h new file mode 100644 index 00000000..2fc1b66b --- /dev/null +++ b/src/core/pop/MCPOPProgressCallback.h @@ -0,0 +1,15 @@ +#ifndef __MAILCORE_MCPOPPROGRESSCALLBACK_H_ + +#define __MAILCORE_MCPOPPROGRESSCALLBACK_H_ + +namespace mailcore { + + class POPSession; + + class POPProgressCallback { + public: + virtual void bodyProgress(POPSession * session, unsigned int current, unsigned int maximum) {}; + }; +} + +#endif diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc new file mode 100644 index 00000000..eea5af90 --- /dev/null +++ b/src/core/pop/MCPOPSession.cc @@ -0,0 +1,545 @@ +#include "MCPOPSession.h" + +#include <string.h> + +#include "MCPOPMessageInfo.h" +#include "MCPOPProgressCallback.h" +#include "MCMessageHeader.h" + +using namespace mailcore; + +enum { + STATE_DISCONNECTED, + STATE_CONNECTED, + STATE_LOGGEDIN, + STATE_LISTED, +}; + +void POPSession::init() +{ + mHostname = NULL; + mPort = 0; + mUsername = NULL; + mPassword = NULL; + mAuthType = AuthTypeSASLNone; + mConnectionType = ConnectionTypeClear; + mCheckCertificateEnabled = true; + mTimeout = 30; + + mPop = NULL; + mCapabilities = POPCapabilityNone; + mProgressCallback = NULL; + mState = STATE_DISCONNECTED; +} + +POPSession::POPSession() +{ + init(); +} + +POPSession::~POPSession() +{ + MC_SAFE_RELEASE(mHostname); + MC_SAFE_RELEASE(mUsername); + MC_SAFE_RELEASE(mPassword); +} + +#if 0 +String * POPSession::className() +{ + return MCSTR("POPSession"); +} +#endif + +void POPSession::setHostname(String * hostname) +{ + MC_SAFE_REPLACE_COPY(String, mHostname, hostname); +} + +String * POPSession::hostname() +{ + return mHostname; +} + +void POPSession::setPort(unsigned int port) +{ + mPort = port; +} + +unsigned int POPSession::port() +{ + return mPort; +} + +void POPSession::setUsername(String * username) +{ + MC_SAFE_REPLACE_COPY(String, mUsername, username); +} + +String * POPSession::username() +{ + return mUsername; +} + +void POPSession::setPassword(String * password) +{ + MC_SAFE_REPLACE_COPY(String, mPassword, password); +} + +String * POPSession::password() +{ + return mPassword; +} + +void POPSession::setAuthType(AuthType authType) +{ + mAuthType = authType; +} + +AuthType POPSession::authType() +{ + return mAuthType; +} + +void POPSession::setConnectionType(ConnectionType connectionType) +{ + mConnectionType = connectionType; +} + +ConnectionType POPSession::connectionType() +{ + return mConnectionType; +} + +void POPSession::setTimeout(time_t timeout) +{ + mTimeout = timeout; +} + +time_t POPSession::timeout() +{ + return mTimeout; +} + +void POPSession::setCheckCertificateEnabled(bool enabled) +{ + mCheckCertificateEnabled = enabled; +} + +bool POPSession::isCheckCertificateEnabled() +{ + return mCheckCertificateEnabled; +} + +bool POPSession::checkCertificate() +{ + // XXX + return true; +} + +void POPSession::bodyProgress(unsigned int current, unsigned int maximum) +{ + if (mProgressCallback != NULL) { + mProgressCallback->bodyProgress(this, current, maximum); + } +} + +void POPSession::body_progress(size_t current, size_t maximum, void * context) +{ + POPSession * session; + + session = (POPSession *) context; + session->bodyProgress((unsigned int) current, (unsigned int) maximum); +} + +void POPSession::setup() +{ + mPop = mailpop3_new(0, NULL); +} + +void POPSession::unsetup() +{ + if (mPop != NULL) { + if (mPop->pop3_stream != NULL) { + mailstream_close(mPop->pop3_stream); + mPop->pop3_stream = NULL; + } + mailpop3_free(mPop); + mPop = NULL; + } +} + +void POPSession::connectIfNeeded(ErrorCode * pError) +{ + if (mState == STATE_DISCONNECTED) { + connect(pError); + } + else { + * pError = ErrorNone; + } +} + +void POPSession::connect(ErrorCode * pError) +{ + int r; + + setup(); + + switch (mConnectionType) { + case ConnectionTypeStartTLS: + MCLog("connect %s %u", MCUTF8(hostname()), (unsigned int) port()); + r = mailpop3_socket_connect(mPop, MCUTF8(hostname()), port()); + if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorConnection; + return; + } + + MCLog("start TLS"); + r = mailpop3_socket_starttls(mPop); + if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorStartTLSNotAvailable; + return; + } + MCLog("done"); + if (!checkCertificate()) { + * pError = ErrorCertificate; + return; + } + break; + + case ConnectionTypeTLS: + MCLog("connect %s %u", MCUTF8(hostname()), (unsigned int) port()); + r = mailpop3_ssl_connect(mPop, MCUTF8(hostname()), port()); + if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorConnection; + return; + } + if (!checkCertificate()) { + * pError = ErrorCertificate; + return; + } + break; + + default: + r = mailpop3_socket_connect(mPop, MCUTF8(hostname()), port()); + if (r != MAILIMAP_NO_ERROR) { + * pError = ErrorConnection; + return; + } + break; + } + + mailstream_low * low; + String * identifierString; + char * identifier; + + low = mailstream_get_low(mPop->pop3_stream); + if (mUsername != NULL) { + identifierString = String::stringWithUTF8Format("%s@%s:%u", MCUTF8(mUsername), MCUTF8(mHostname), mPort); + } + else { + identifierString = String::stringWithUTF8Format("%s:%u", MCUTF8(mUsername), mPort); + } + identifier = strdup(identifierString->UTF8Characters()); + mailstream_low_set_identifier(low, identifier); + mState = STATE_CONNECTED; + * pError = ErrorNone; +} + +void POPSession::disconnect() +{ + if (mPop == NULL) + return; + + mailpop3_quit(mPop); + mState = STATE_DISCONNECTED; + unsetup(); +} + +void POPSession::loginIfNeeded(ErrorCode * pError) +{ + connectIfNeeded(pError); + if (* pError != ErrorNone) + return; + + if (mState == STATE_CONNECTED) { + login(pError); + } + else { + * pError = ErrorNone; + } +} + +void POPSession::login(ErrorCode * pError) +{ + int r; + const char * utf8username; + const char * utf8password; + + utf8username = MCUTF8(username()); + utf8password = MCUTF8(password()); + if (utf8username == NULL) { + utf8username = ""; + } + if (utf8password == NULL) { + utf8password = ""; + } + + switch (authType()) { + case 0: + default: + r = mailpop3_user(mPop, utf8username); + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorAuthentication; + return; + } + + r = mailpop3_pass(mPop, utf8password); + break; + + case AuthTypeSASLCRAMMD5: + r = mailpop3_auth(mPop, "CRAM-MD5", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL); + break; + + case AuthTypeSASLPlain: + r = mailpop3_auth(mPop, "PLAIN", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL); + break; + + case AuthTypeSASLGSSAPI: + // needs to be tested + r = mailpop3_auth(mPop, "GSSAPI", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL /* realm */); + break; + + case AuthTypeSASLDIGESTMD5: + r = mailpop3_auth(mPop, "DIGEST-MD5", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL); + break; + + case AuthTypeSASLLogin: + r = mailpop3_auth(mPop, "LOGIN", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL); + break; + + case AuthTypeSASLSRP: + r = mailpop3_auth(mPop, "SRP", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL); + break; + + case AuthTypeSASLNTLM: + r = mailpop3_auth(mPop, "NTLM", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL /* realm */); + break; + + case AuthTypeSASLKerberosV4: + r = mailpop3_auth(mPop, "KERBEROS_V4", + MCUTF8(hostname()), + NULL, + NULL, + utf8username, utf8username, + utf8password, NULL /* realm */); + break; + } + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorAuthentication; + return; + } + + mState = STATE_LOGGEDIN; + * pError = ErrorNone; +} + +Array * POPSession::fetchMessages(ErrorCode * pError) +{ + int r; + carray * msg_list; + + loginIfNeeded(pError); + if (* pError != ErrorNone) { + return NULL; + } + + r = mailpop3_list(mPop, &msg_list); + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return NULL; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorFetchMessageList; + return NULL; + } + + Array * result = Array::array(); + for(unsigned int i = 0 ; i < carray_count(msg_list) ; i ++) { + struct mailpop3_msg_info * msg_info; + String * uid; + + msg_info = (struct mailpop3_msg_info *) carray_get(msg_list, i); + if (msg_info->msg_uidl == NULL) + continue; + + uid = String::stringWithUTF8Characters(msg_info->msg_uidl); + + POPMessageInfo * info = new POPMessageInfo(); + info->setUid(uid); + info->setIndex(msg_info->msg_index); + result->addObject(info); + info->release(); + } + + * pError = ErrorNone; + mState = STATE_LISTED; + + return result; +} + +void POPSession::listIfNeeded(ErrorCode * pError) +{ + if (mState == STATE_LISTED) { + * pError = ErrorNone; + return; + } + + fetchMessages(pError); +} + +MessageHeader * POPSession::fetchHeader(unsigned int index, ErrorCode * pError) +{ + int r; + char * content; + size_t content_len; + + listIfNeeded(pError); + if (* pError != ErrorNone) { + return NULL; + } + + r = mailpop3_top(mPop, index, 0, &content, &content_len); + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return NULL; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorFetch; + return NULL; + } + + Data * data; + data = new Data(content, (unsigned int) content_len); + MessageHeader * result = new MessageHeader(); + result->importHeadersData(data); + result->autorelease(); + data->release(); + + mailpop3_top_free(content); + * pError = ErrorNone; + + return result; +} + +MessageHeader * POPSession::fetchHeader(POPMessageInfo * msg, ErrorCode * pError) +{ + return fetchHeader(msg->index(), pError); +} + +Data * POPSession::fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError) +{ + int r; + char * content; + size_t content_len; + + listIfNeeded(pError); + if (* pError != ErrorNone) { + return NULL; + } + + mProgressCallback = callback; + + r = mailpop3_retr(mPop, index, &content, &content_len); + mProgressCallback = NULL; + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return NULL; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorFetch; + return NULL; + } + + Data * result; + result = Data::dataWithBytes(content, (unsigned int) content_len); + mailpop3_retr_free(content); + * pError = ErrorNone; + + return result; +} + +Data * POPSession::fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError) +{ + return fetchMessage(msg->index(), callback, pError); +} + +void POPSession::deleteMessage(unsigned int index, ErrorCode * pError) +{ + int r; + + listIfNeeded(pError); + if (* pError != ErrorNone) { + return; + } + + r = mailpop3_dele(mPop, index); + if (r == MAILPOP3_ERROR_STREAM) { + * pError = ErrorConnection; + return; + } + else if (r != MAILPOP3_NO_ERROR) { + * pError = ErrorDeleteMessage; + return; + } + + * pError = ErrorNone; +} + +void POPSession::deleteMessage(POPMessageInfo * msg, ErrorCode * pError) +{ + deleteMessage(msg->index(), pError); +} diff --git a/src/core/pop/MCPOPSession.h b/src/core/pop/MCPOPSession.h new file mode 100644 index 00000000..ef6c132b --- /dev/null +++ b/src/core/pop/MCPOPSession.h @@ -0,0 +1,90 @@ +#ifndef __MAILCORE_MCPOPSESSION_H_ + +#define __MAILCORE_MCPOPSESSION_H_ + +#include <mailcore/MCBaseTypes.h> +#include <mailcore/MCMessageConstants.h> +#include <libetpan/libetpan.h> + +namespace mailcore { + + class POPMessageInfo; + class POPProgressCallback; + class MessageHeader; + + class POPSession : public Object { + private: + String * mHostname; + unsigned int mPort; + String * mUsername; + String * mPassword; + AuthType mAuthType; + ConnectionType mConnectionType; + bool mCheckCertificateEnabled; + time_t mTimeout; + + mailpop3 * mPop; + POPCapability mCapabilities; + POPProgressCallback * mProgressCallback; + int mState; + + void init(); + void bodyProgress(unsigned int current, unsigned int maximum); + bool checkCertificate(); + static void body_progress(size_t current, size_t maximum, void * context); + void setup(); + void unsetup(); + void connectIfNeeded(ErrorCode * pError); + void loginIfNeeded(ErrorCode * pError); + void listIfNeeded(ErrorCode * pError); + + public: + POPSession(); + virtual ~POPSession(); + + //virtual String * className(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); + + virtual void setPort(unsigned int port); + virtual unsigned int port(); + + virtual void setUsername(String * login); + virtual String * username(); + + virtual void setPassword(String * password); + virtual String * password(); + + virtual void setAuthType(AuthType authType); + virtual AuthType authType(); + + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); + + virtual void setTimeout(time_t timeout); + virtual time_t timeout(); + + virtual void setCheckCertificateEnabled(bool enabled); + virtual bool isCheckCertificateEnabled(); + + virtual void connect(ErrorCode * pError); + virtual void disconnect(); + + virtual void login(ErrorCode * pError); + + Array * fetchMessages(ErrorCode * pError); + + MessageHeader * fetchHeader(unsigned int index, ErrorCode * pError); + MessageHeader * fetchHeader(POPMessageInfo * msg, ErrorCode * pError); + + Data * fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError); + Data * fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError); + + void deleteMessage(unsigned int index, ErrorCode * pError); + void deleteMessage(POPMessageInfo * msg, ErrorCode * pError); + }; + +} + +#endif |