summaryrefslogtreecommitdiff
authoralwin <alwin>2004-02-12 22:24:30 (UTC)
committer alwin <alwin>2004-02-12 22:24:30 (UTC)
commitc7f102b944a5172ca330dfc3c0f83cf0b9c65100 (patch) (side-by-side diff)
treeb4bdfea3a7eeb6a46f949cfdaa7052ac25e1c128
parent596d87e16d593cbc52d510973ece99ffe26cd4c4 (diff)
downloadopie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.zip
opie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.tar.gz
opie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.tar.bz2
TLS support for SMTP
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp51
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.h3
2 files changed, 53 insertions, 1 deletions
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
index e8db9ca..3ab6b77 100644
--- a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
@@ -38,48 +38,50 @@ void SMTPwrapper::emitQCop( int queued ) {
QCopEnvelope env( "QPE/Pim", "outgoingMails(int)" );
env << queued;
}
QString SMTPwrapper::mailsmtpError( int errnum ) {
switch ( errnum ) {
case MAILSMTP_NO_ERROR:
return tr( "No error" );
case MAILSMTP_ERROR_UNEXPECTED_CODE:
return tr( "Unexpected error code" );
case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
return tr( "Service not available" );
case MAILSMTP_ERROR_STREAM:
return tr( "Stream error" );
case MAILSMTP_ERROR_HOSTNAME:
return tr( "gethostname() failed" );
case MAILSMTP_ERROR_NOT_IMPLEMENTED:
return tr( "Not implemented" );
case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
return tr( "Error, action not taken" );
case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
return tr( "Data exceeds storage allocation" );
case MAILSMTP_ERROR_IN_PROCESSING:
return tr( "Error in processing" );
+ case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED:
+ return tr( "Starttls not supported" );
// case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
// return tr( "Insufficient system storage" );
case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
return tr( "Mailbox unavailable" );
case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
return tr( "Mailbox name not allowed" );
case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
return tr( "Bad command sequence" );
case MAILSMTP_ERROR_USER_NOT_LOCAL:
return tr( "User not local" );
case MAILSMTP_ERROR_TRANSACTION_FAILED:
return tr( "Transaction failed" );
case MAILSMTP_ERROR_MEMORY:
return tr( "Memory error" );
case MAILSMTP_ERROR_CONNECTION_REFUSED:
return tr( "Connection refused" );
default:
return tr( "Unknown error code" );
}
}
mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail ) {
return mailimf_mailbox_new( strdup( name.latin1() ),
strdup( mail.latin1() ) );
@@ -544,99 +546,142 @@ void SMTPwrapper::smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ) {
from = getFrom( mail );
rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
smtpSend(from,rcpts,data,size,smtp);
if (data) {
free(data);
}
if (from) {
free(from);
}
if (rcpts)
smtp_address_list_free( rcpts );
}
void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage)
{
if (data) {
storeMail(data,size,"Sendfailed");
}
if (failuremessage) {
QMessageBox::critical(0,tr("Error sending mail"),
tr("<center>%1</center>").arg(failuremessage));
}
}
+int SMTPwrapper::start_smtp_tls(mailsmtp *session)
+{
+ if (!session) {
+ return MAILSMTP_ERROR_IN_PROCESSING;
+ }
+ int err = mailesmtp_starttls(session);
+ if (err != MAILSMTP_NO_ERROR) return err;
+ mailstream_low * low;
+ mailstream_low * new_low;
+ low = mailstream_get_low(session->stream);
+ if (!low) {
+ return MAILSMTP_ERROR_IN_PROCESSING;
+ }
+ 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(session->stream, new_low);
+ } else {
+ return MAILSMTP_ERROR_IN_PROCESSING;
+ }
+ return err;
+}
+
int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ) {
const char *server, *user, *pass;
bool ssl;
uint16_t port;
mailsmtp *session;
int err,result;
QString failuretext = "";
result = 1;
server = user = pass = 0;
server = smtp->getServer().latin1();
// FIXME: currently only TLS and Plain work.
ssl = false;
+ bool try_tls = true;
+ bool force_tls=false;
if ( smtp->ConnectionType() == 2 ) {
ssl = true;
+ try_tls = false;
+ } else if (smtp->ConnectionType() == 1) {
+ force_tls = true;
}
port = smtp->getPort().toUInt();
session = mailsmtp_new( 20, &progress );
if ( session == NULL ) {
/* no failure message cause this happens when problems with memory - than we
we can not display any messagebox */
return 0;
}
qDebug( "Servername %s at port %i", server, port );
if ( ssl ) {
qDebug( "SSL session" );
err = mailsmtp_ssl_connect( session, server, port );
} else {
qDebug( "No SSL session" );
err = mailsmtp_socket_connect( session, server, port );
}
if ( err != MAILSMTP_NO_ERROR ) {
qDebug("Error init connection");
failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err));
result = 0;
}
+ /* switch to tls after init 'cause there it will send the ehlo */
if (result) {
err = mailsmtp_init( session );
if (err != MAILSMTP_NO_ERROR) {
result = 0;
failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err));
}
}
+ if (try_tls) {
+ err = start_smtp_tls(session);
+ if (err != MAILSMTP_NO_ERROR) {
+ try_tls = false;
+ } else {
+ err = mailesmtp_ehlo(session);
+ }
+ }
+
+ if (!try_tls && force_tls) {
+ result = 0;
+ failuretext = tr("Error init SMTP tls: %1").arg(mailsmtpError(err));
+ }
+
if (result==1 && smtp->getLogin() ) {
qDebug("smtp with auth");
if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
// get'em
LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = login.getUser().latin1();
pass = login.getPassword().latin1();
} else {
result = 0;
failuretext=tr("Login aborted - storing mail to localfolder");
}
} else {
user = smtp->getUser().latin1();
pass = smtp->getPassword().latin1();
}
qDebug( "session->auth: %i", session->auth);
if (result) {
err = mailsmtp_auth( session, (char*)user, (char*)pass );
if ( err == MAILSMTP_NO_ERROR ) {
qDebug("auth ok");
} else {
@@ -716,65 +761,69 @@ int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which
if (rcpts && from) {
res = smtpSend(from,rcpts,data->Content(),data->Length(),smtp );
}
if (fields) {
mailimf_fields_free(fields);
fields = 0;
}
if (data) {
delete data;
}
if (from) {
free(from);
}
if (rcpts) {
smtp_address_list_free( rcpts );
}
return res;
}
/* this is a special fun */
bool SMTPwrapper::flushOutbox(SMTPaccount*smtp) {
bool returnValue = true;
- if (!smtp)
+ qDebug("Sending the queue");
+ if (!smtp) {
+ qDebug("No smtp account given");
return false;
+ }
bool reset_user_value = false;
QString localfolders = AbstractMail::defaultLocalfolder();
AbstractMail*wrap = AbstractMail::getWrapper(localfolders);
if (!wrap) {
qDebug("memory error");
return false;
}
QString oldPw, oldUser;
QList<RecMail> mailsToSend;
QList<RecMail> mailsToRemove;
QString mbox("Outgoing");
wrap->listMessages(mbox,mailsToSend);
if (mailsToSend.count()==0) {
delete wrap;
+ qDebug("No mails to send");
return false;
}
oldPw = smtp->getPassword();
oldUser = smtp->getUser();
if (smtp->getLogin() && (smtp->getUser().isEmpty() || smtp->getPassword().isEmpty()) ) {
// get'em
QString user,pass;
LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = login.getUser().latin1();
pass = login.getPassword().latin1();
reset_user_value = true;
smtp->setUser(user);
smtp->setPassword(pass);
} else {
return true;
}
}
mailsToSend.setAutoDelete(false);
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h
index 89826d9..75e4891 100644
--- a/noncore/net/mail/libmailwrapper/smtpwrapper.h
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h
@@ -1,73 +1,76 @@
#ifndef SMTPwrapper_H
#define SMTPwrapper_H
#include <qpe/applnk.h>
#include <qbitarray.h>
#include <qdatetime.h>
#include <libetpan/clist.h>
#include "settings.h"
class Mail;
class AbstractMail;
class RecMail;
class Attachment;
struct mailimf_fields;
struct mailimf_field;
struct mailimf_mailbox;
struct mailmime;
struct mailimf_address_list;
class progressMailSend;
+struct mailsmtp;
class SMTPwrapper : public QObject
{
Q_OBJECT
public:
SMTPwrapper( Settings *s );
virtual ~SMTPwrapper(){}
void sendMail(const Mail& mail,SMTPaccount*smtp,bool later=false );
bool flushOutbox(SMTPaccount*smtp);
static progressMailSend*sendProgress;
signals:
void queuedMails( int );
protected:
mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
mailimf_fields *createImfFields(const Mail &mail );
mailmime *createMimeMail(const Mail&mail );
mailimf_address_list *parseAddresses(const QString&addr );
void addFileParts( mailmime *message,const QList<Attachment>&files );
mailmime *buildTxtPart(const QString&str );
mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content);
void smtpSend( mailmime *mail,bool later, SMTPaccount *smtp );
clist *createRcptList( mailimf_fields *fields );
static void storeMail(const char*mail, size_t length, const QString&box);
static QString mailsmtpError( int err );
static void progress( size_t current, size_t maximum );
static void addRcpts( clist *list, mailimf_address_list *addr_list );
static char *getFrom( mailmime *mail );
static char *getFrom( mailimf_field *ffrom);
static mailimf_field *getField( mailimf_fields *fields, int type );
+ static int start_smtp_tls(mailsmtp *session);
+
int smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp );
void storeMail(mailmime*mail, const QString&box);
Settings *settings;
int sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which);
void storeFailedMail(const char*data,unsigned int size, const char*failuremessage);
int m_queuedMail;
static const char* USER_AGENT;
protected slots:
void emitQCop( int queued );
};
#endif