author | alwin <alwin> | 2004-02-12 22:24:30 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-02-12 22:24:30 (UTC) |
commit | c7f102b944a5172ca330dfc3c0f83cf0b9c65100 (patch) (unidiff) | |
tree | b4bdfea3a7eeb6a46f949cfdaa7052ac25e1c128 /noncore | |
parent | 596d87e16d593cbc52d510973ece99ffe26cd4c4 (diff) | |
download | opie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.zip opie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.tar.gz opie-c7f102b944a5172ca330dfc3c0f83cf0b9c65100.tar.bz2 |
TLS support for SMTP
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.cpp | 51 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.h | 3 |
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 | |||
@@ -50,24 +50,26 @@ QString SMTPwrapper::mailsmtpError( int errnum ) { | |||
50 | case MAILSMTP_ERROR_STREAM: | 50 | case MAILSMTP_ERROR_STREAM: |
51 | return tr( "Stream error" ); | 51 | return tr( "Stream error" ); |
52 | case MAILSMTP_ERROR_HOSTNAME: | 52 | case MAILSMTP_ERROR_HOSTNAME: |
53 | return tr( "gethostname() failed" ); | 53 | return tr( "gethostname() failed" ); |
54 | case MAILSMTP_ERROR_NOT_IMPLEMENTED: | 54 | case MAILSMTP_ERROR_NOT_IMPLEMENTED: |
55 | return tr( "Not implemented" ); | 55 | return tr( "Not implemented" ); |
56 | case MAILSMTP_ERROR_ACTION_NOT_TAKEN: | 56 | case MAILSMTP_ERROR_ACTION_NOT_TAKEN: |
57 | return tr( "Error, action not taken" ); | 57 | return tr( "Error, action not taken" ); |
58 | case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION: | 58 | case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION: |
59 | return tr( "Data exceeds storage allocation" ); | 59 | return tr( "Data exceeds storage allocation" ); |
60 | case MAILSMTP_ERROR_IN_PROCESSING: | 60 | case MAILSMTP_ERROR_IN_PROCESSING: |
61 | return tr( "Error in processing" ); | 61 | return tr( "Error in processing" ); |
62 | case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED: | ||
63 | return tr( "Starttls not supported" ); | ||
62 | // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE: | 64 | // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE: |
63 | // return tr( "Insufficient system storage" ); | 65 | // return tr( "Insufficient system storage" ); |
64 | case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE: | 66 | case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE: |
65 | return tr( "Mailbox unavailable" ); | 67 | return tr( "Mailbox unavailable" ); |
66 | case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED: | 68 | case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED: |
67 | return tr( "Mailbox name not allowed" ); | 69 | return tr( "Mailbox name not allowed" ); |
68 | case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND: | 70 | case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND: |
69 | return tr( "Bad command sequence" ); | 71 | return tr( "Bad command sequence" ); |
70 | case MAILSMTP_ERROR_USER_NOT_LOCAL: | 72 | case MAILSMTP_ERROR_USER_NOT_LOCAL: |
71 | return tr( "User not local" ); | 73 | return tr( "User not local" ); |
72 | case MAILSMTP_ERROR_TRANSACTION_FAILED: | 74 | case MAILSMTP_ERROR_TRANSACTION_FAILED: |
73 | return tr( "Transaction failed" ); | 75 | return tr( "Transaction failed" ); |
@@ -556,42 +558,70 @@ void SMTPwrapper::smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ) { | |||
556 | 558 | ||
557 | void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage) | 559 | void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage) |
558 | { | 560 | { |
559 | if (data) { | 561 | if (data) { |
560 | storeMail(data,size,"Sendfailed"); | 562 | storeMail(data,size,"Sendfailed"); |
561 | } | 563 | } |
562 | if (failuremessage) { | 564 | if (failuremessage) { |
563 | QMessageBox::critical(0,tr("Error sending mail"), | 565 | QMessageBox::critical(0,tr("Error sending mail"), |
564 | tr("<center>%1</center>").arg(failuremessage)); | 566 | tr("<center>%1</center>").arg(failuremessage)); |
565 | } | 567 | } |
566 | } | 568 | } |
567 | 569 | ||
570 | int SMTPwrapper::start_smtp_tls(mailsmtp *session) | ||
571 | { | ||
572 | if (!session) { | ||
573 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
574 | } | ||
575 | int err = mailesmtp_starttls(session); | ||
576 | if (err != MAILSMTP_NO_ERROR) return err; | ||
577 | mailstream_low * low; | ||
578 | mailstream_low * new_low; | ||
579 | low = mailstream_get_low(session->stream); | ||
580 | if (!low) { | ||
581 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
582 | } | ||
583 | int fd = mailstream_low_get_fd(low); | ||
584 | if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { | ||
585 | mailstream_low_free(low); | ||
586 | mailstream_set_low(session->stream, new_low); | ||
587 | } else { | ||
588 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
589 | } | ||
590 | return err; | ||
591 | } | ||
592 | |||
568 | int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ) { | 593 | int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ) { |
569 | const char *server, *user, *pass; | 594 | const char *server, *user, *pass; |
570 | bool ssl; | 595 | bool ssl; |
571 | uint16_t port; | 596 | uint16_t port; |
572 | mailsmtp *session; | 597 | mailsmtp *session; |
573 | int err,result; | 598 | int err,result; |
574 | QString failuretext = ""; | 599 | QString failuretext = ""; |
575 | 600 | ||
576 | result = 1; | 601 | result = 1; |
577 | server = user = pass = 0; | 602 | server = user = pass = 0; |
578 | server = smtp->getServer().latin1(); | 603 | server = smtp->getServer().latin1(); |
579 | 604 | ||
580 | // FIXME: currently only TLS and Plain work. | 605 | // FIXME: currently only TLS and Plain work. |
581 | 606 | ||
582 | ssl = false; | 607 | ssl = false; |
608 | bool try_tls = true; | ||
609 | bool force_tls=false; | ||
583 | 610 | ||
584 | if ( smtp->ConnectionType() == 2 ) { | 611 | if ( smtp->ConnectionType() == 2 ) { |
585 | ssl = true; | 612 | ssl = true; |
613 | try_tls = false; | ||
614 | } else if (smtp->ConnectionType() == 1) { | ||
615 | force_tls = true; | ||
586 | } | 616 | } |
587 | 617 | ||
588 | port = smtp->getPort().toUInt(); | 618 | port = smtp->getPort().toUInt(); |
589 | 619 | ||
590 | session = mailsmtp_new( 20, &progress ); | 620 | session = mailsmtp_new( 20, &progress ); |
591 | if ( session == NULL ) { | 621 | if ( session == NULL ) { |
592 | /* no failure message cause this happens when problems with memory - than we | 622 | /* no failure message cause this happens when problems with memory - than we |
593 | we can not display any messagebox */ | 623 | we can not display any messagebox */ |
594 | return 0; | 624 | return 0; |
595 | } | 625 | } |
596 | 626 | ||
597 | qDebug( "Servername %s at port %i", server, port ); | 627 | qDebug( "Servername %s at port %i", server, port ); |
@@ -599,32 +629,47 @@ int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMT | |||
599 | qDebug( "SSL session" ); | 629 | qDebug( "SSL session" ); |
600 | err = mailsmtp_ssl_connect( session, server, port ); | 630 | err = mailsmtp_ssl_connect( session, server, port ); |
601 | } else { | 631 | } else { |
602 | qDebug( "No SSL session" ); | 632 | qDebug( "No SSL session" ); |
603 | err = mailsmtp_socket_connect( session, server, port ); | 633 | err = mailsmtp_socket_connect( session, server, port ); |
604 | } | 634 | } |
605 | if ( err != MAILSMTP_NO_ERROR ) { | 635 | if ( err != MAILSMTP_NO_ERROR ) { |
606 | qDebug("Error init connection"); | 636 | qDebug("Error init connection"); |
607 | failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); | 637 | failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); |
608 | result = 0; | 638 | result = 0; |
609 | } | 639 | } |
610 | 640 | ||
641 | /* switch to tls after init 'cause there it will send the ehlo */ | ||
611 | if (result) { | 642 | if (result) { |
612 | err = mailsmtp_init( session ); | 643 | err = mailsmtp_init( session ); |
613 | if (err != MAILSMTP_NO_ERROR) { | 644 | if (err != MAILSMTP_NO_ERROR) { |
614 | result = 0; | 645 | result = 0; |
615 | failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); | 646 | failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); |
616 | } | 647 | } |
617 | } | 648 | } |
618 | 649 | ||
650 | if (try_tls) { | ||
651 | err = start_smtp_tls(session); | ||
652 | if (err != MAILSMTP_NO_ERROR) { | ||
653 | try_tls = false; | ||
654 | } else { | ||
655 | err = mailesmtp_ehlo(session); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | if (!try_tls && force_tls) { | ||
660 | result = 0; | ||
661 | failuretext = tr("Error init SMTP tls: %1").arg(mailsmtpError(err)); | ||
662 | } | ||
663 | |||
619 | if (result==1 && smtp->getLogin() ) { | 664 | if (result==1 && smtp->getLogin() ) { |
620 | qDebug("smtp with auth"); | 665 | qDebug("smtp with auth"); |
621 | if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) { | 666 | if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) { |
622 | // get'em | 667 | // get'em |
623 | LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true ); | 668 | LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true ); |
624 | login.show(); | 669 | login.show(); |
625 | if ( QDialog::Accepted == login.exec() ) { | 670 | if ( QDialog::Accepted == login.exec() ) { |
626 | // ok | 671 | // ok |
627 | user = login.getUser().latin1(); | 672 | user = login.getUser().latin1(); |
628 | pass = login.getPassword().latin1(); | 673 | pass = login.getPassword().latin1(); |
629 | } else { | 674 | } else { |
630 | result = 0; | 675 | result = 0; |
@@ -728,41 +773,45 @@ int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which | |||
728 | free(from); | 773 | free(from); |
729 | } | 774 | } |
730 | if (rcpts) { | 775 | if (rcpts) { |
731 | smtp_address_list_free( rcpts ); | 776 | smtp_address_list_free( rcpts ); |
732 | } | 777 | } |
733 | return res; | 778 | return res; |
734 | } | 779 | } |
735 | 780 | ||
736 | /* this is a special fun */ | 781 | /* this is a special fun */ |
737 | bool SMTPwrapper::flushOutbox(SMTPaccount*smtp) { | 782 | bool SMTPwrapper::flushOutbox(SMTPaccount*smtp) { |
738 | bool returnValue = true; | 783 | bool returnValue = true; |
739 | 784 | ||
740 | if (!smtp) | 785 | qDebug("Sending the queue"); |
786 | if (!smtp) { | ||
787 | qDebug("No smtp account given"); | ||
741 | return false; | 788 | return false; |
789 | } | ||
742 | 790 | ||
743 | bool reset_user_value = false; | 791 | bool reset_user_value = false; |
744 | QString localfolders = AbstractMail::defaultLocalfolder(); | 792 | QString localfolders = AbstractMail::defaultLocalfolder(); |
745 | AbstractMail*wrap = AbstractMail::getWrapper(localfolders); | 793 | AbstractMail*wrap = AbstractMail::getWrapper(localfolders); |
746 | if (!wrap) { | 794 | if (!wrap) { |
747 | qDebug("memory error"); | 795 | qDebug("memory error"); |
748 | return false; | 796 | return false; |
749 | } | 797 | } |
750 | QString oldPw, oldUser; | 798 | QString oldPw, oldUser; |
751 | QList<RecMail> mailsToSend; | 799 | QList<RecMail> mailsToSend; |
752 | QList<RecMail> mailsToRemove; | 800 | QList<RecMail> mailsToRemove; |
753 | QString mbox("Outgoing"); | 801 | QString mbox("Outgoing"); |
754 | wrap->listMessages(mbox,mailsToSend); | 802 | wrap->listMessages(mbox,mailsToSend); |
755 | if (mailsToSend.count()==0) { | 803 | if (mailsToSend.count()==0) { |
756 | delete wrap; | 804 | delete wrap; |
805 | qDebug("No mails to send"); | ||
757 | return false; | 806 | return false; |
758 | } | 807 | } |
759 | 808 | ||
760 | oldPw = smtp->getPassword(); | 809 | oldPw = smtp->getPassword(); |
761 | oldUser = smtp->getUser(); | 810 | oldUser = smtp->getUser(); |
762 | if (smtp->getLogin() && (smtp->getUser().isEmpty() || smtp->getPassword().isEmpty()) ) { | 811 | if (smtp->getLogin() && (smtp->getUser().isEmpty() || smtp->getPassword().isEmpty()) ) { |
763 | // get'em | 812 | // get'em |
764 | QString user,pass; | 813 | QString user,pass; |
765 | LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true ); | 814 | LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true ); |
766 | login.show(); | 815 | login.show(); |
767 | if ( QDialog::Accepted == login.exec() ) { | 816 | if ( QDialog::Accepted == login.exec() ) { |
768 | // ok | 817 | // ok |
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 | |||
@@ -10,24 +10,25 @@ | |||
10 | #include "settings.h" | 10 | #include "settings.h" |
11 | 11 | ||
12 | class Mail; | 12 | class Mail; |
13 | class AbstractMail; | 13 | class AbstractMail; |
14 | class RecMail; | 14 | class RecMail; |
15 | class Attachment; | 15 | class Attachment; |
16 | struct mailimf_fields; | 16 | struct mailimf_fields; |
17 | struct mailimf_field; | 17 | struct mailimf_field; |
18 | struct mailimf_mailbox; | 18 | struct mailimf_mailbox; |
19 | struct mailmime; | 19 | struct mailmime; |
20 | struct mailimf_address_list; | 20 | struct mailimf_address_list; |
21 | class progressMailSend; | 21 | class progressMailSend; |
22 | struct mailsmtp; | ||
22 | 23 | ||
23 | class SMTPwrapper : public QObject | 24 | class SMTPwrapper : public QObject |
24 | { | 25 | { |
25 | Q_OBJECT | 26 | Q_OBJECT |
26 | 27 | ||
27 | public: | 28 | public: |
28 | SMTPwrapper( Settings *s ); | 29 | SMTPwrapper( Settings *s ); |
29 | virtual ~SMTPwrapper(){} | 30 | virtual ~SMTPwrapper(){} |
30 | void sendMail(const Mail& mail,SMTPaccount*smtp,bool later=false ); | 31 | void sendMail(const Mail& mail,SMTPaccount*smtp,bool later=false ); |
31 | bool flushOutbox(SMTPaccount*smtp); | 32 | bool flushOutbox(SMTPaccount*smtp); |
32 | 33 | ||
33 | static progressMailSend*sendProgress; | 34 | static progressMailSend*sendProgress; |
@@ -45,24 +46,26 @@ protected: | |||
45 | mailmime *buildTxtPart(const QString&str ); | 46 | mailmime *buildTxtPart(const QString&str ); |
46 | mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content); | 47 | mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content); |
47 | void smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ); | 48 | void smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ); |
48 | clist *createRcptList( mailimf_fields *fields ); | 49 | clist *createRcptList( mailimf_fields *fields ); |
49 | 50 | ||
50 | static void storeMail(const char*mail, size_t length, const QString&box); | 51 | static void storeMail(const char*mail, size_t length, const QString&box); |
51 | static QString mailsmtpError( int err ); | 52 | static QString mailsmtpError( int err ); |
52 | static void progress( size_t current, size_t maximum ); | 53 | static void progress( size_t current, size_t maximum ); |
53 | static void addRcpts( clist *list, mailimf_address_list *addr_list ); | 54 | static void addRcpts( clist *list, mailimf_address_list *addr_list ); |
54 | static char *getFrom( mailmime *mail ); | 55 | static char *getFrom( mailmime *mail ); |
55 | static char *getFrom( mailimf_field *ffrom); | 56 | static char *getFrom( mailimf_field *ffrom); |
56 | static mailimf_field *getField( mailimf_fields *fields, int type ); | 57 | static mailimf_field *getField( mailimf_fields *fields, int type ); |
58 | static int start_smtp_tls(mailsmtp *session); | ||
59 | |||
57 | int smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ); | 60 | int smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ); |
58 | 61 | ||
59 | void storeMail(mailmime*mail, const QString&box); | 62 | void storeMail(mailmime*mail, const QString&box); |
60 | Settings *settings; | 63 | Settings *settings; |
61 | 64 | ||
62 | int sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which); | 65 | int sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which); |
63 | void storeFailedMail(const char*data,unsigned int size, const char*failuremessage); | 66 | void storeFailedMail(const char*data,unsigned int size, const char*failuremessage); |
64 | 67 | ||
65 | int m_queuedMail; | 68 | int m_queuedMail; |
66 | static const char* USER_AGENT; | 69 | static const char* USER_AGENT; |
67 | 70 | ||
68 | protected slots: | 71 | protected slots: |