Version: (using KDE KDE 3.5.5) Installed from: Ubuntu Packages OS: Linux There is currently no support for SMTP authentication for sending emails. Since some servers require SMTP authentication, this would be a useful feature.
SVN commit 607540 by toma: Rewritten the smtp part. Should behave a lot better + preparations for auth on smtp. BUG:137698 CCBUG:136360 M +0 -1 TODO M +3 -2 src/Makefile.am M +13 -153 src/composer.cpp M +3 -20 src/composer.h M +1 -0 src/imap.cpp M +1 -1 src/imap.h A src/smtp.cpp [License: GPL (v2+)] A src/smtp.h [License: GPL (v2+)] M +21 -23 src/socketsafe.cpp M +6 -0 src/socketsafe.h --- trunk/playground/pim/mailody/TODO #607539:607540 @@ -38,5 +38,4 @@ Known Bugs: when not correctly logged in, no message. it just waits. Put a timer on that? copy an existing message and paste it in a new message, links are still blue - smtp broken --- trunk/playground/pim/mailody/src/Makefile.am #607539:607540 @@ -2,7 +2,7 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libkmime $(all_includes) # these are the headers for your project -noinst_HEADERS = mainwindow.h db.h imap.h messagedata.h \ +noinst_HEADERS = mainwindow.h db.h imap.h smtp.h messagedata.h \ headerlistview.h mailboxlistview.h messageview.h \ setup.h setupaccount.h sidebar.h colorquotes.h \ socketsafe.h composer.h filebrowser.h global.h \ @@ -24,7 +24,8 @@ bin_PROGRAMS = mailody # the application source, library search path, and link libraries -mailody_SOURCES = main.cpp mainwindow.cpp imap.cpp db.cpp messagedata.cpp \ +mailody_SOURCES = main.cpp mainwindow.cpp imap.cpp smtp.cpp db.cpp m\ + messagedata.cpp \ headerlistview.cpp mailboxlistview.cpp messageview.cpp \ setup.cpp setupaccount.cpp sidebar.cpp colorquotes.cpp \ socketsafe.cpp composer.cpp filebrowser.cpp global.cpp \ --- trunk/playground/pim/mailody/src/composer.cpp #607539:607540 @@ -45,11 +45,11 @@ #include "sidebar.h" #include "imap.h" #include "global.h" -#include "socketsafe.h" #include "filebrowser.h" #include "datalistview.h" #include "addresslineedit.h" #include "composer.h" +#include "smtp.h" namespace Mailody { @@ -58,7 +58,6 @@ : KMainWindow(0), m_lastState(To), m_smtp(0), - m_currentCommand(Connecting), m_close(false), m_dirty(false) { @@ -729,7 +728,7 @@ if (totalSize > 2000000) { - int i = KMessageBox::warningContinueCancel(this, + int i = KMessageBox::warningContinueCancel(this, i18n("The size of the attachments is %1, are you " "sure you want to send it?") .arg( KIO::convertSize(KIO::filesize_t(totalSize))), @@ -748,47 +747,19 @@ // Sending it!!! Yeah! + Imap* t = Imap::instance(); + t->saveMessage(m_mailbox, m->encodedContent( true )); + if (m_smtp) delete m_smtp; - m_currentCommand = Connecting; - - QString server = smtp_server.section(":",0,0); - int port = smtp_server.section(":",1,1).toInt(); - switch(safe) - { - case 0: - if (port == 0) - port = 25; - m_smtp = new SocketSafe(this, server, port, SocketSafe::NONE); - break; - case 1: - if (port == 0) - port = 465; - m_smtp = new SocketSafe(this, server, port, SocketSafe::SSL); - break; - case 2: - if (port == 0) - port = 25; - m_smtp = new SocketSafe(this, server, port, SocketSafe::TLS); - break; - } - - - connect(m_smtp, SIGNAL(data(const QString&)), - SLOT(slotRead(const QString&))); - connect(m_smtp, SIGNAL(connected()), SLOT(slotConnected())); - m_smtp->reconnect(); + m_smtp = new SMTP(this, "SMTP"); connect(m_smtp, SIGNAL(error(const QString&)), SLOT(slotError(const QString&))); - connect(m_smtp, SIGNAL(readyfortls()), - SLOT(slotTLS())); + connect(m_smtp, SIGNAL(done()),SLOT(slotDone())); -} + m_smtp->send(m_tos, m->encodedContent()); -void Composer::slotTLS() -{ - m_smtp->write("starttls"); } void Composer::slotSetDirty() @@ -796,128 +767,17 @@ m_dirty = true; } -void Composer::slotError(const QString& error) +void Composer::slotDone() { - //kdDebug()<< "slotError " << error << endl; - // There is a 10% chance for a crash remaining here - // on a timeout error - // Thiago guarded for that for KDE 3.5.6 - comitted on 2006-10-29 - if (m_smtp) - { - m_smtp->deleteLater(); - m_smtp = 0; - } - - KMessageBox::information(this, error); + m_close = true; + close(); } -void Composer::slotRead(const QString& dataIn) +void Composer::slotError(const QString& error) { - // kdDebug() << "Received: " << dataIn.stripWhiteSpace() - // << " for the command " << m_currentCommand << endl; - - static QString lastEmail; - - if (!m_smtp) - return; - - if (m_currentCommand == Connecting) - { - m_currentCommand = Helo; - m_smtp->write("helo localhost"); - } - else if (m_currentCommand == Helo) - { - m_currentCommand = From; - m_smtp->write("MAIL FROM:" + m->from()->email()); - } - else if (m_currentCommand == From || !m_tos.isEmpty()) - { - // Please remember, this can be the response to hte Helo or to - // a previous RCPT command.... - if (!dataIn.startsWith("250")) - { - if (dataIn.startsWith("501")) - showError(i18n("One of the emailaddress was refused by the " - "server. The refused address is: " + lastEmail)); - else - showError( dataIn ); - return; - } - - m_currentCommand = Rcpt; - QString to = m_tos.first(); - m_tos.pop_front(); - - //only send the actual emailaddress, not the name. - KMime::Headers::AddressField Address; - Address.fromUnicodeString( to,"UTF-8"); - lastEmail = Address.email(); - - m_smtp->write("RCPT TO:" + lastEmail); - } - else if (m_currentCommand == Rcpt ) - { - if (!dataIn.startsWith("250")) - { - if (dataIn.startsWith("501")) - showError(i18n("One of the emailaddress was refused by the " - "server. The refused address is: " + lastEmail)); - else - showError( dataIn ); - return; - } - m_currentCommand = Data; - m_smtp->write("DATA"); - } - else if (m_currentCommand == Data) - { - if (!dataIn.startsWith("250") && !dataIn.startsWith("354")) - { - showError( dataIn ); - return; - } - m_currentCommand = Quit; - m_smtp->write(m->encodedContent()); - m_smtp->write("\r\n."); - } - else if (m_currentCommand == Quit) - { - if (!dataIn.startsWith("250") && !dataIn.startsWith("354")) - { - showError( dataIn ); - return; - } - m_currentCommand = Done; - m_smtp->aboutToClose(); // prevent disconnect message. - m_smtp->write("QUIT"); - } - else if (m_currentCommand == Done) - { - // Time to store the message: - Imap* t = Imap::instance(); - t->saveMessage(m_mailbox, m->encodedContent( true )); - m_close = true; - close(); - } + KMessageBox::information(this, error); } -void Composer::showError(const QString& error) -{ - //kdDebug()<< "showError " << error << endl; - m_currentCommand = NotDone; - m_smtp->aboutToClose(); - m_smtp->write("QUIT"); - m_smtp = 0; - KMessageBox::error(this, i18n("The message can not be send, de server " - "answered:\n\n"+error)); } -void Composer::slotConnected() -{ - kdDebug() << "Connected! " << endl; -} - -} - #include "composer.moc" --- trunk/playground/pim/mailody/src/composer.h #607539:607540 @@ -53,7 +53,7 @@ class AddressLineEdit; class DataListView; -class SocketSafe; +class SMTP; /** * @class Composer @@ -117,17 +117,6 @@ private: - enum Commands{ - None=0, - Connecting, - Helo, - From, - Rcpt, - Data, - Quit, - Done, - NotDone - }; AddressLineEdit *m_edit; DataListView *m_lv; @@ -141,8 +130,7 @@ QSplitter* m_vhsplitter; KLineEdit* m_subject; KTextEdit* m_text; - SocketSafe* m_smtp; - Commands m_currentCommand; + SMTP* m_smtp; KMime::Message* m; QStringList m_tos; QPushButton* m_add; @@ -177,13 +165,8 @@ const QPoint &point); void slotContextMenuAddressList(KListView*, QListViewItem* lvi, const QPoint &point); - - - void slotSend(); - void slotConnected(); - void slotTLS(); - void slotRead(const QString&); + void slotDone(); void slotError(const QString& error); void slotSetDirty(); }; --- trunk/playground/pim/mailody/src/imap.cpp #607539:607540 @@ -751,6 +751,7 @@ connect(m_imap, SIGNAL(data(const QString&)), SLOT(slotRead(const QString&))); + connect(m_imap, SIGNAL(TLSCompleted()), SLOT(slotLogin())); connect(m_imap, SIGNAL(connected()), SLOT(slotLogin())); connect(m_imap, SIGNAL(error(const QString&)), SLOT(slotError(const QString&))); --- trunk/playground/pim/mailody/src/imap.h #607539:607540 @@ -79,7 +79,7 @@ /** * Contructor */ - Imap( QWidget* parent, const char* name ); + explicit Imap( QWidget* parent, const char* name ); /** * Destructor --- trunk/playground/pim/mailody/src/socketsafe.cpp #607539:607540 @@ -326,7 +326,7 @@ << "), but accepted previously... " << endl; } - emit connected(); + emit TLSCompleted(); m_ready = true; } @@ -362,25 +362,32 @@ // The bits received are not crypted. This can happen when // we don't want tls or ssl or when the connection is ready for tls. - if (m_safe == TLS) - { - QString msg = m_socket->readLine(); + static QString received; + uint available = m_socket->bytesAvailable(); + QByteArray buffer(available); + m_socket->readBlock(buffer.data(), buffer.size()); + QCString cs; + cs.resize(buffer.size()+1); + memcpy(cs.data(), buffer.data(), buffer.size()); + QString msg = cs.data(); + #ifdef comm_debug - kdDebug() << "S(0): " << QString(msg).stripWhiteSpace() << endl; + kdDebug() << "S(0): " << msg.stripWhiteSpace() << endl; #endif + if (m_safe == TLS) + { // handle the tls case. + // TODO move intelligence to imap/smtp if (msg.find("a02 OK") != -1 || - msg.find("220 Ready to start TLS") != -1) + msg.find("220 ") < msg.find("TLS") && msg.find("220 ") != -1) { // Request accepted. kdDebug() << "Accepted, starting TLS handshake..." << endl; m_ssl->startClient(m_server); m_crypted=true; } - else if (msg.find("a02 ") != -1 || msg.find("error",0,false) != -1 || - msg.find("500") != -1 || msg.find("503") != -1 || - msg.find("501") != -1 || msg.find("502") != -1) + else if (msg.find("a02 ") != -1) { // request returned, but not ok. KMessageBox::information(0,i18n("TLS was refused:\n\n")+msg); @@ -388,26 +395,17 @@ else { // request tls. - kdDebug() << "Connected, starting request for TLS" << endl; + kdDebug() << "Connected, emitting req. to deal with TLS" << endl; emit readyfortls(); + emit data(msg); } } else { + received.append(msg); + // we don't need any encryption, so gather stuff and emit it. - static QString received; - uint available = m_socket->bytesAvailable(); - QByteArray buffer(available); - m_socket->readBlock(buffer.data(), buffer.size()); - QCString cs; - cs.resize(buffer.size()+1); - memcpy(cs.data(), buffer.data(), buffer.size()); - QString t = cs.data(); - received.append(t); -#ifdef comm_debug - kdDebug() << "S(0): " << t.stripWhiteSpace() << endl; -#endif - QStringList splitted = QStringList::split("\n",t); + QStringList splitted = QStringList::split("\n",msg); if (!m_gather || splitted.grep(QRegExp("^a02")).count() != 0) { emit data(received); --- trunk/playground/pim/mailody/src/socketsafe.h #607539:607540 @@ -122,7 +122,13 @@ */ void connected(); + /** + * emitted when TLS is done + */ + void TLSCompleted(); + + /** * emitted when the dns request is ok (pretty useless, but still). */ void hostFound();
SVN commit 607785 by toma: Support for Authentication for SMTP. BUG: 136360 M +131 -58 setupaccount.cpp M +53 -21 smtp.cpp M +6 -0 smtp.h