-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 @@ -28,32 +28,84 @@ int IMAPwrapper::selectMbox(const QString&mbox) } 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; @@ -67,68 +119,88 @@ void IMAPwrapper::login() 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 = ""; } 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 @@ -39,32 +39,33 @@ public: 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); |