author | alwin <alwin> | 2004-01-29 15:06:30 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-01-29 15:06:30 (UTC) |
commit | 9ccf499bd8d213ec9a5e8aede7c55a4b4e77ae0d (patch) (side-by-side diff) | |
tree | 9d5844721558146c84dc3e5efb19424be78b4fec | |
parent | 6e34e6e90f3ea6a18101395afc7cf5fe86c427e8 (diff) | |
download | opie-9ccf499bd8d213ec9a5e8aede7c55a4b4e77ae0d.zip opie-9ccf499bd8d213ec9a5e8aede7c55a4b4e77ae0d.tar.gz opie-9ccf499bd8d213ec9a5e8aede7c55a4b4e77ae0d.tar.bz2 |
tls support for IMAP implemented
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.cpp | 84 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.h | 1 |
2 files changed, 79 insertions, 6 deletions
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp index 098dbdc..1dfcc4c 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp @@ -1,214 +1,286 @@ #include <stdlib.h> #include <libetpan/libetpan.h> #include <qpe/global.h> #include "imapwrapper.h" #include "mailtypes.h" #include "logindialog.h" IMAPwrapper::IMAPwrapper( IMAPaccount *a ) : AbstractMail() { account = a; m_imap = 0; m_Lastmbox = ""; } IMAPwrapper::~IMAPwrapper() { logout(); } /* to avoid to often select statements in loops etc. we trust that we are logged in and connection is established!*/ int IMAPwrapper::selectMbox(const QString&mbox) { if (mbox == m_Lastmbox) { return MAILIMAP_NO_ERROR; } int err = mailimap_select( m_imap, (char*)mbox.latin1()); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); m_Lastmbox = ""; return err; } m_Lastmbox = mbox; return err; } void IMAPwrapper::imap_progress( size_t current, size_t maximum ) { qDebug( "IMAP: %i of %i", current, maximum ); } +bool IMAPwrapper::start_tls(bool force_tls) +{ + int err; + bool try_tls; + mailimap_capability_data * cap_data = 0; + + err = mailimap_capability(m_imap,&cap_data); + if (err != MAILIMAP_NO_ERROR) { + Global::statusMessage("error getting capabilities!"); + qDebug("error getting capabilities!"); + return false; + } + clistiter * cur; + for(cur = clist_begin(cap_data->cap_list) ; cur != NULL;cur = clist_next(cur)) { + struct mailimap_capability * cap; + cap = (struct mailimap_capability *)clist_content(cur); + if (cap->cap_type == MAILIMAP_CAPABILITY_NAME) { + if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) { + try_tls = true; + break; + } + } + } + if (cap_data) { + mailimap_capability_data_free(cap_data); + } + if (try_tls) { + err = mailimap_starttls(m_imap); + if (err != MAILIMAP_NO_ERROR && force_tls) { + Global::statusMessage(tr("Server has no TLS support!")); + qDebug("Server has no TLS support!"); + try_tls = false; + } else { + mailstream_low * low; + mailstream_low * new_low; + low = mailstream_get_low(m_imap->imap_stream); + if (!low) { + try_tls = false; + } else { + int fd = mailstream_low_get_fd(low); + if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { + mailstream_low_free(low); + mailstream_set_low(m_imap->imap_stream, new_low); + } else { + try_tls = false; + } + } + } + } + return try_tls; +} + void IMAPwrapper::login() { const char *server, *user, *pass; uint16_t port; int err = MAILIMAP_NO_ERROR; if (account->getOffline()) return; /* we are connected this moment */ /* TODO: setup a timer holding the line or if connection closed - delete the value */ if (m_imap) { err = mailimap_noop(m_imap); if (err!=MAILIMAP_NO_ERROR) { logout(); } else { mailstream_flush(m_imap->imap_stream); return; } } server = account->getServer().latin1(); port = account->getPort().toUInt(); if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser().latin1(); pass = login.getPassword().latin1(); } else { // cancel qDebug( "IMAP: Login canceled" ); return; } } else { user = account->getUser().latin1(); pass = account->getPassword().latin1(); } m_imap = mailimap_new( 20, &imap_progress ); - - /* connect */ - bool ssl = false; + bool try_tls = false; + bool force_tls = false; if ( account->ConnectionType() == 2 ) { ssl = true; } + if (account->ConnectionType()==1) { + force_tls = true; + } if ( ssl ) { qDebug( "using ssl" ); err = mailimap_ssl_connect( m_imap, (char*)server, port ); } else { err = mailimap_socket_connect( m_imap, (char*)server, port ); } if ( err != MAILIMAP_NO_ERROR && err != MAILIMAP_NO_ERROR_AUTHENTICATED && err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) { QString failure = ""; if (err == MAILIMAP_ERROR_CONNECTION_REFUSED) { failure="Connection refused"; } else { failure="Unknown failure"; } Global::statusMessage(tr("error connecting imap server: %1").arg(failure)); mailimap_free( m_imap ); m_imap = 0; return; } + if (!ssl) { + try_tls = start_tls(force_tls); + } + + bool ok = true; + if (force_tls && !try_tls) { + Global::statusMessage(tr("Server has no TLS support!")); + qDebug("Server has no TLS support!"); + ok = false; + } + + /* login */ - err = mailimap_login_simple( m_imap, (char*)user, (char*)pass ); - if ( err != MAILIMAP_NO_ERROR ) { - Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response)); + + if (ok) { + err = mailimap_login_simple( m_imap, (char*)user, (char*)pass ); + if ( err != MAILIMAP_NO_ERROR ) { + Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response)); + ok = false; + } + } + if (!ok) { err = mailimap_close( m_imap ); mailimap_free( m_imap ); m_imap = 0; } } void IMAPwrapper::logout() { int err = MAILIMAP_NO_ERROR; if (!m_imap) return; err = mailimap_logout( m_imap ); err = mailimap_close( m_imap ); mailimap_free( m_imap ); m_imap = 0; m_Lastmbox = ""; } void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target ) { int err = MAILIMAP_NO_ERROR; clist *result = 0; clistcell *current; mailimap_fetch_type *fetchType = 0; mailimap_set *set = 0; login(); if (!m_imap) { return; } /* select mailbox READONLY for operations */ err = selectMbox(mailbox); if ( err != MAILIMAP_NO_ERROR ) { return; } int last = m_imap->imap_selection_info->sel_exists; if (last == 0) { Global::statusMessage(tr("Mailbox has no mails")); return; } else { } /* the range has to start at 1!!! not with 0!!!! */ set = mailimap_set_new_interval( 1, last ); fetchType = mailimap_fetch_type_new_fetch_att_list_empty(); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size()); err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); QString date,subject,from; if ( err == MAILIMAP_NO_ERROR ) { mailimap_msg_att * msg_att; int i = 0; for (current = clist_begin(result); current != 0; current=clist_next(current)) { ++i; msg_att = (mailimap_msg_att*)current->data; RecMail*m = parse_list_result(msg_att); if (m) { m->setNumber(i); m->setMbox(mailbox); m->setWrapper(this); target.append(m); } } Global::statusMessage(tr("Mailbox has %1 mails").arg(target.count())); } else { Global::statusMessage(tr("Error fetching headers: %1").arg(m_imap->imap_response)); } if (result) mailimap_fetch_list_free(result); } QList<Folder>* IMAPwrapper::listFolders() { const char *path, *mask; int err = MAILIMAP_NO_ERROR; clist *result = 0; clistcell *current = 0; clistcell*cur_flag = 0; mailimap_mbx_list_flags*bflags = 0; QList<Folder> * folders = new QList<Folder>(); folders->setAutoDelete( false ); login(); if (!m_imap) { return folders; } /* * First we have to check for INBOX 'cause it sometimes it's not inside the path. diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h index c10f86a..0a1fe2c 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.h +++ b/noncore/net/mail/libmailwrapper/imapwrapper.h @@ -1,77 +1,78 @@ #ifndef __IMAPWRAPPER #define __IMAPWRAPPER #include <qlist.h> #include "mailwrapper.h" #include "abstractmail.h" #include <libetpan/clist.h> struct mailimap; struct mailimap_body; struct mailimap_body_type_1part; struct mailimap_body_type_text; struct mailimap_body_type_basic; struct mailimap_body_type_msg; struct mailimap_body_type_mpart; struct mailimap_body_fields; struct mailimap_msg_att; class encodedString; class IMAPwrapper : public AbstractMail { Q_OBJECT public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); virtual QList<Folder>* listFolders(); virtual void listMessages(const QString & mailbox,QList<RecMail>&target ); virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); virtual void deleteMail(const RecMail&mail); virtual void answeredMail(const RecMail&mail); virtual int deleteAllMail(const Folder*folder); virtual void storeMessage(const char*msg,size_t length, const QString&folder); virtual void mvcpAllMails(Folder*fromFolder,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); virtual void mvcpMail(const RecMail&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); virtual RecBody fetchBody(const RecMail&mail); virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); virtual encodedString* fetchRawBody(const RecMail&mail); virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false); virtual int deleteMbox(const Folder*folder); static void imap_progress( size_t current, size_t maximum ); virtual void logout(); virtual const QString&getType()const; virtual const QString&getName()const; protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); + bool start_tls(bool force=true); virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call); int selectMbox(const QString&mbox); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); void fillMultiPart(RecPart&target_part,mailimap_body_type_mpart*which); void traverseBody(const RecMail&mail,mailimap_body*body,RecBody&target_body,int current_recursion,QValueList<int>recList,int current_count=1); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); IMAPaccount *account; mailimap *m_imap; QString m_Lastmbox; }; #endif |