SMTP over SSL (untested, feedback requested)
authorChristoph Hohmann <reboot@gmx.ch>
Fri, 27 Jul 2001 17:24:14 +0000 (17:24 +0000)
committerChristoph Hohmann <reboot@gmx.ch>
Fri, 27 Jul 2001 17:24:14 +0000 (17:24 +0000)
IMAP over SSL

ChangeLog.claws
src/imap.c
src/imap.h
src/prefs_account.c
src/prefs_account.h
src/send.c
src/ssl.c

index ba43fded6f6071f452b504d72c3558ce62f62a5f..c5ba232240f0edce60f011682aa0563359904a52 100644 (file)
@@ -6,6 +6,16 @@
        * src/prefs_scoring.c
                scroll list when moving rows up or down
 
+       * src/imap.c
+       * src/imap.h
+       * src/prefs_account.c
+       * src/prefs_account.h
+       * src/send.c
+               SMTP over SSL (untested, feedback requested)
+               IMAP over SSL
+       * src/ssl.c
+               code cleanup
+
 2001-07-26 [alfons]
        
        * configure.in, acconfig.h
index 02b99ad2b8b7c64270525708b4584ee89d5a47c1..bb0494fa36ed8fcd87761979e30f37352d8aa623 100644 (file)
 #include "codeconv.h"
 #include "utils.h"
 #include "inputdialog.h"
+#include "ssl.h"
 
 #define IMAP4_PORT     143
+#if USE_SSL
+#define IMAPS_PORT     993
+#endif
 
 static GList *session_list = NULL;
 
@@ -78,9 +82,16 @@ static GSList *imap_delete_cached_messages   (GSList         *mlist,
                                                 guint32         last_uid);
 static void imap_delete_all_cached_messages    (FolderItem     *item);
 
+#if !USE_SSL
 static SockInfo *imap_open             (const gchar    *server,
                                         gushort         port,
                                         gchar          *buf);
+#else
+static SockInfo *imap_open             (const gchar    *server,
+                                        gushort         port,
+                                        gchar          *buf,
+                                        gboolean        use_ssl);
+#endif
 
 static gint imap_set_message_flags     (IMAPSession    *session,
                                         guint32         first_uid,
@@ -215,14 +226,26 @@ static IMAPSession *imap_session_get(Folder *folder)
        g_return_val_if_fail(folder->type == F_IMAP, NULL);
        g_return_val_if_fail(folder->account != NULL, NULL);
 
+#if !USE_SSL
        port = folder->account->set_imapport ? folder->account->imapport
                : IMAP4_PORT;
+#else
+       port = folder->account->set_imapport ? folder->account->imapport
+               : (folder->account->imap_ssl ? IMAPS_PORT : IMAP4_PORT);
+#endif
 
        if (!rfolder->session) {
                rfolder->session =
+#if !USE_SSL
                        imap_session_new(folder->account->recv_server, port,
                                         folder->account->userid,
                                         folder->account->passwd);
+#else
+                       imap_session_new(folder->account->recv_server, port,
+                                        folder->account->userid,
+                                        folder->account->passwd,
+                                        folder->account->imap_ssl);
+#endif
                if (rfolder->session)
                        imap_parse_namespace(IMAP_SESSION(rfolder->session),
                                             IMAP_FOLDER(folder));
@@ -236,9 +259,16 @@ static IMAPSession *imap_session_get(Folder *folder)
                            folder->account->recv_server, port);
                session_destroy(rfolder->session);
                rfolder->session =
+#if !USE_SSL
                        imap_session_new(folder->account->recv_server, port,
                                         folder->account->userid,
                                         folder->account->passwd);
+#else
+                       imap_session_new(folder->account->recv_server, port,
+                                        folder->account->userid,
+                                        folder->account->passwd,
+                                        folder->account->imap_ssl);
+#endif
                if (rfolder->session)
                        imap_parse_namespace(IMAP_SESSION(rfolder->session),
                                             IMAP_FOLDER(folder));
@@ -261,8 +291,14 @@ static gchar *imap_query_password(const gchar *server, const gchar *user)
        return pass;
 }
 
+#if !USE_SSL
 Session *imap_session_new(const gchar *server, gushort port,
                          const gchar *user, const gchar *pass)
+#else
+Session *imap_session_new(const gchar *server, gushort port,
+                         const gchar *user, const gchar *pass,
+                         gboolean use_ssl)
+#endif
 {
        gchar buf[IMAPBUFSIZE];
        IMAPSession *session;
@@ -283,7 +319,11 @@ Session *imap_session_new(const gchar *server, gushort port,
        log_message(_("creating IMAP4 connection to %s:%d ...\n"),
                    server, port);
 
+#if !USE_SSL
        if ((imap_sock = imap_open(server, port, buf)) == NULL)
+#else
+       if ((imap_sock = imap_open(server, port, buf, use_ssl)) == NULL)
+#endif
                return NULL;
        if (imap_cmd_login(imap_sock, user, pass) != IMAP_SUCCESS) {
                imap_cmd_logout(imap_sock);
@@ -307,6 +347,9 @@ Session *imap_session_new(const gchar *server, gushort port,
 
 void imap_session_destroy(IMAPSession *session)
 {
+#if USE_SSL
+       ssl_done_socket(SESSION(session)->sock);
+#endif
        sock_close(SESSION(session)->sock);
        SESSION(session)->sock = NULL;
 
@@ -1232,7 +1275,11 @@ static void imap_delete_all_cached_messages(FolderItem *item)
        debug_print(_("done.\n"));
 }
 
+#if !USE_SSL
 static SockInfo *imap_open(const gchar *server, gushort port, gchar *buf)
+#else
+static SockInfo *imap_open(const gchar *server, gushort port, gchar *buf, gboolean use_ssl)
+#endif
 {
        SockInfo *sock;
 
@@ -1242,6 +1289,13 @@ static SockInfo *imap_open(const gchar *server, gushort port, gchar *buf)
                return NULL;
        }
 
+#if USE_SSL
+       if(use_ssl && !ssl_init_socket(sock)) {
+               sock_close(sock);
+               return NULL;
+       }
+#endif
+
        imap_cmd_count = 0;
 
        if (imap_cmd_noop(sock) != IMAP_SUCCESS) {
index 958ad8476e84aabf1dc7053f58963b2f1d0608f7..96a7716efed5b34a5de64b34366a826884533ce4 100644 (file)
@@ -70,10 +70,18 @@ typedef enum
 #define IMAP_IS_DELETED(flags) ((flags & IMAP_FLAG_DELETED) != 0)
 #define IMAP_IS_DRAFT(flags)   ((flags & IMAP_FLAG_DRAFT) != 0)
 
+#if !USE_SSL
 Session *imap_session_new              (const gchar    *server,
                                         gushort         port,
                                         const gchar    *user,
                                         const gchar    *pass);
+#else
+Session *imap_session_new              (const gchar    *server,
+                                        gushort         port,
+                                        const gchar    *user,
+                                        const gchar    *pass,
+                                        gboolean        use_ssl);
+#endif
 void imap_session_destroy              (IMAPSession    *session);
 void imap_session_destroy_all          (void);
 
index 0ec03659640fef9d5d686d159efcde611529bfbd..e79d9a823d9b49c455df0c23ba07124bb9f8298e 100644 (file)
@@ -130,9 +130,6 @@ static struct Advanced {
        GtkWidget *popport_hbox;
        GtkWidget *popport_chkbtn;
        GtkWidget *popport_entry;
-#if USE_SSL
-       GtkWidget *popssl_chkbtn;
-#endif
        GtkWidget *imapport_hbox;
        GtkWidget *imapport_chkbtn;
        GtkWidget *imapport_entry;
@@ -141,6 +138,11 @@ static struct Advanced {
        GtkWidget *nntpport_entry;
        GtkWidget *domain_chkbtn;
        GtkWidget *domain_entry;
+#if USE_SSL
+       GtkWidget *smtpssl_chkbtn;
+       GtkWidget *popssl_chkbtn;
+       GtkWidget *imapssl_chkbtn;
+#endif
 } advanced;
 
 static void prefs_account_fix_size                     (void);
@@ -310,12 +312,6 @@ static PrefParam param[] = {
         &advanced.popport_entry,
         prefs_set_data_from_entry, prefs_set_entry},
 
-#if USE_SSL
-       {"pop_ssl", "FALSE", &tmp_ac_prefs.pop_ssl, P_BOOL,
-        &advanced.popssl_chkbtn,
-        prefs_set_data_from_toggle, prefs_set_toggle},
-#endif
-
        {"set_imapport", "FALSE", &tmp_ac_prefs.set_imapport, P_BOOL,
         &advanced.imapport_chkbtn,
         prefs_set_data_from_toggle, prefs_set_toggle},
@@ -340,6 +336,20 @@ static PrefParam param[] = {
         &advanced.domain_entry,
         prefs_set_data_from_entry, prefs_set_entry},
 
+#if USE_SSL
+       {"smtp_ssl", "FALSE", &tmp_ac_prefs.smtp_ssl, P_BOOL,
+        &advanced.smtpssl_chkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
+
+       {"pop_ssl", "FALSE", &tmp_ac_prefs.pop_ssl, P_BOOL,
+        &advanced.popssl_chkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
+
+       {"imap_ssl", "FALSE", &tmp_ac_prefs.imap_ssl, P_BOOL,
+        &advanced.imapssl_chkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
+#endif
+
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
@@ -1214,9 +1224,6 @@ static void prefs_account_advanced_create(void)
        GtkWidget *hbox_popport;
        GtkWidget *checkbtn_popport;
        GtkWidget *entry_popport;
-#ifdef USE_SSL
-       GtkWidget *checkbtn_popssl;
-#endif
        GtkWidget *hbox_imapport;
        GtkWidget *checkbtn_imapport;
        GtkWidget *entry_imapport;
@@ -1225,6 +1232,11 @@ static void prefs_account_advanced_create(void)
        GtkWidget *entry_nntpport;
        GtkWidget *checkbtn_domain;
        GtkWidget *entry_domain;
+#ifdef USE_SSL
+       GtkWidget *checkbtn_smtpssl;
+       GtkWidget *checkbtn_popssl;
+       GtkWidget *checkbtn_imapssl;
+#endif
 
 #define PACK_HBOX(hbox) \
 { \
@@ -1255,6 +1267,10 @@ static void prefs_account_advanced_create(void)
        PACK_PORT_ENTRY (hbox1, entry_smtpport);
        SET_TOGGLE_SENSITIVITY (checkbtn_smtpport, entry_smtpport);
 
+#ifdef USE_SSL
+       PACK_CHECK_BUTTON (vbox2, checkbtn_smtpssl, _("Use SSL to connect to SMTP server"));
+#endif
+
        PACK_HBOX (hbox_popport);
        PACK_CHECK_BUTTON (hbox_popport, checkbtn_popport,
                           _("Specify POP3 port"));
@@ -1271,6 +1287,10 @@ static void prefs_account_advanced_create(void)
        PACK_PORT_ENTRY (hbox_imapport, entry_imapport);
        SET_TOGGLE_SENSITIVITY (checkbtn_imapport, entry_imapport);
 
+#ifdef USE_SSL
+       PACK_CHECK_BUTTON (vbox2, checkbtn_imapssl, _("Use SSL to connect to IMAP server"));
+#endif
+
        PACK_HBOX (hbox_nntpport);
        PACK_CHECK_BUTTON (hbox_nntpport, checkbtn_nntpport,
                           _("Specify NNTP port"));
@@ -1294,7 +1314,9 @@ static void prefs_account_advanced_create(void)
        advanced.popport_chkbtn         = checkbtn_popport;
        advanced.popport_entry          = entry_popport;
 #ifdef USE_SSL
+       advanced.smtpssl_chkbtn          = checkbtn_smtpssl;
        advanced.popssl_chkbtn           = checkbtn_popssl;
+       advanced.imapssl_chkbtn          = checkbtn_imapssl;
 #endif
        advanced.imapport_hbox          = hbox_imapport;
        advanced.imapport_chkbtn        = checkbtn_imapport;
@@ -1545,6 +1567,11 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem)
                gtk_widget_hide(advanced.popport_hbox);
                gtk_widget_hide(advanced.imapport_hbox);
                gtk_widget_show(advanced.nntpport_hbox);
+
+#if USE_SSL
+               gtk_widget_hide(advanced.popssl_chkbtn);
+               gtk_widget_hide(advanced.imapssl_chkbtn);
+#endif
                break;
        case A_LOCAL:
                gtk_widget_set_sensitive(basic.inbox_label, TRUE);
@@ -1594,6 +1621,11 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem)
                gtk_widget_hide(advanced.nntpport_hbox);
                prefs_account_mailcmd_toggled
                        (GTK_TOGGLE_BUTTON(basic.mailcmd_chkbtn), NULL);
+
+#if USE_SSL
+               gtk_widget_hide(advanced.popssl_chkbtn);
+               gtk_widget_hide(advanced.imapssl_chkbtn);
+#endif
                break;
        case A_IMAP4:
                gtk_widget_set_sensitive(basic.inbox_label, FALSE);
@@ -1645,6 +1677,11 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem)
                gtk_widget_hide(advanced.popport_hbox);
                gtk_widget_show(advanced.imapport_hbox);
                gtk_widget_hide(advanced.nntpport_hbox);
+
+#if USE_SSL
+               gtk_widget_hide(advanced.popssl_chkbtn);
+               gtk_widget_show(advanced.imapssl_chkbtn);
+#endif
                break;
        case A_POP3:
        default:
@@ -1697,6 +1734,11 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem)
                gtk_widget_show(advanced.popport_hbox);
                gtk_widget_hide(advanced.imapport_hbox);
                gtk_widget_hide(advanced.nntpport_hbox);
+
+#if USE_SSL
+               gtk_widget_show(advanced.popssl_chkbtn);
+               gtk_widget_hide(advanced.imapssl_chkbtn);
+#endif
                break;
        }
 
index 45ca63821e5e909c8dd9d38bd15268376e832a7e..8d8f364c25975e44a0fa74541c8239b5a29dc2fe 100644 (file)
@@ -110,15 +110,17 @@ struct _PrefsAccount
        gushort   smtpport;
        gboolean  set_popport;
        gushort   popport;
-#if USE_SSL
-       gboolean  pop_ssl;
-#endif
        gboolean  set_imapport;
        gushort   imapport;
        gboolean  set_nntpport;
        gushort   nntpport;
        gboolean  set_domain;
        gchar    *domain;
+#if USE_SSL
+       gboolean  smtp_ssl;
+       gboolean  pop_ssl;
+       gboolean  imap_ssl;
+#endif
 
        /* Default or not */
        gboolean is_default;
index ad182fda40a5c679af0f9db3c4f2debe47f6ebf3..ea74478525d714148785f1b0d209db2fa45cfcc6 100644 (file)
@@ -48,6 +48,9 @@
 #include "gtkutils.h"
 
 #define SMTP_PORT      25
+#if USE_SSL
+#define SSMTP_PORT     465
+#endif
 
 typedef struct _SendProgressDialog     SendProgressDialog;
 
@@ -58,13 +61,25 @@ struct _SendProgressDialog
        gboolean cancelled;
 };
 
+#if !USE_SSL
 static gint send_message_smtp  (GSList *to_list, const gchar *from,
                                 const gchar *server, gushort port,
                                 const gchar *domain, const gchar *userid,
                                 const gchar *passwd, gboolean use_smtp_auth,
                                 FILE *fp);
+
 static SockInfo *send_smtp_open        (const gchar *server, gushort port,
                                 const gchar *domain, gboolean use_smtp_auth);
+#else
+static gint send_message_smtp  (GSList *to_list, const gchar *from,
+                                const gchar *server, gushort port,
+                                const gchar *domain, const gchar *userid,
+                                const gchar *passwd, gboolean use_smtp_auth,
+                                FILE *fp, gboolean use_ssl);
+
+static SockInfo *send_smtp_open        (const gchar *server, gushort port,
+                                const gchar *domain, gboolean use_smtp_auth, gboolean use_ssl);
+#endif
 
 static SendProgressDialog *send_progress_dialog_create(void);
 static void send_progress_dialog_destroy(SendProgressDialog *dialog);
@@ -94,13 +109,21 @@ gint send_message(const gchar *file, PrefsAccount *ac_prefs, GSList *to_list)
                                                ac_prefs->mail_command,
                                                fp);
        } else {
+#if USE_SSL
+               port = ac_prefs->set_smtpport ? ac_prefs->smtpport : (ac_prefs->smtp_ssl ? SSMTP_PORT : SMTP_PORT);
+#else
                port = ac_prefs->set_smtpport ? ac_prefs->smtpport : SMTP_PORT;
+#endif
                domain = ac_prefs->set_domain ? ac_prefs->domain : NULL;
 
                val = send_message_smtp(to_list, ac_prefs->address,
                                        ac_prefs->smtp_server, port, domain,
                                         ac_prefs->userid, ac_prefs->passwd,
-                                       ac_prefs->use_smtp_auth, fp);
+                                       ac_prefs->use_smtp_auth, fp
+#if USE_SSL
+                                       , ac_prefs->smtp_ssl
+#endif
+                                       );
        }
 
        fclose(fp);
@@ -211,16 +234,32 @@ gint send_message_queue(const gchar *file)
                }
 
                if (ac) {
+#if !USE_SSL
                        port = ac->set_smtpport ? ac->smtpport : SMTP_PORT;
+#else
+                       port = ac->set_smtpport ? ac->smtpport : (ac->smtp_ssl ? SSMTP_PORT : SMTP_PORT);
+#endif
                        domain = ac->set_domain ? ac->domain : NULL;
+#if !USE_SSL
                        val = send_message_smtp
                                (to_list, from, server, port, domain,
                                 ac->userid, ac->passwd, ac->use_smtp_auth, fp);
+#else
+                       val = send_message_smtp
+                               (to_list, from, server, port, domain,
+                                ac->userid, ac->passwd, ac->use_smtp_auth, fp, ac->smtp_ssl);
+#endif
                } else {
                        g_warning(_("Account not found.\n"));
+#if !USE_SSL
                        val = send_message_smtp
                                (to_list, from, server, SMTP_PORT, NULL,
                                 NULL, NULL, FALSE, fp);
+#else
+                       val = send_message_smtp
+                               (to_list, from, server, SMTP_PORT, NULL,
+                                NULL, NULL, FALSE, fp, FALSE);
+#endif
                }
        }
 
@@ -266,11 +305,19 @@ gint send_message_queue(const gchar *file)
        } \
 }
 
+#if !USE_SSL
 static gint send_message_smtp(GSList *to_list, const gchar *from,
                              const gchar *server, gushort port,
                              const gchar *domain, const gchar *userid,
                              const gchar *passwd, gboolean use_smtp_auth,
                              FILE *fp)
+#else
+static gint send_message_smtp(GSList *to_list, const gchar *from,
+                             const gchar *server, gushort port,
+                             const gchar *domain, const gchar *userid,
+                             const gchar *passwd, gboolean use_smtp_auth,
+                             FILE *fp, gboolean use_ssl)
+#endif
 {
        SockInfo *smtp_sock = NULL;
        SendProgressDialog *dialog;
@@ -306,9 +353,15 @@ static gint send_message_smtp(GSList *to_list, const gchar *from,
        gtk_clist_set_text(clist, 0, 2, _("Connecting"));
        GTK_EVENTS_FLUSH();
 
+#if !USE_SSL
        SEND_EXIT_IF_ERROR((smtp_sock = send_smtp_open
                                (server, port, domain, use_smtp_auth)),
                           "connecting to server");
+#else
+       SEND_EXIT_IF_ERROR((smtp_sock = send_smtp_open
+                               (server, port, domain, use_smtp_auth, use_ssl)),
+                          "connecting to server");
+#endif
 
        progress_dialog_set_label(dialog->dialog, _("Sending MAIL FROM..."));
        gtk_clist_set_text(clist, 0, 2, _("Sending"));
@@ -364,14 +417,23 @@ static gint send_message_smtp(GSList *to_list, const gchar *from,
        SEND_EXIT_IF_NOTOK(smtp_eom(smtp_sock), "terminating data");
        SEND_EXIT_IF_NOTOK(smtp_quit(smtp_sock), "sending QUIT");
 
+#if USE_SSL
+       ssl_done_socket(smtp_sock);
+#endif
+
        sock_close(smtp_sock);
        send_progress_dialog_destroy(dialog);
 
        return 0;
 }
 
+#if !USE_SSL
 static SockInfo *send_smtp_open(const gchar *server, gushort port,
                           const gchar *domain, gboolean use_smtp_auth)
+#else
+static SockInfo *send_smtp_open(const gchar *server, gushort port,
+                          const gchar *domain, gboolean use_smtp_auth, gboolean use_ssl)
+#endif
 {
        SockInfo *sock;
        gint val;
@@ -384,6 +446,14 @@ static SockInfo *send_smtp_open(const gchar *server, gushort port,
                return NULL;
        }
 
+#if USE_SSL
+       if(use_ssl && !ssl_init_socket(sock)) {
+               log_warning(_("SSL connection failed"));
+               sock_close(sock);
+               return NULL;
+       }
+#endif
+
        if (smtp_ok(sock) == SM_OK) {
                val = smtp_helo(sock, domain ? domain : get_domain_name(),
                                use_smtp_auth);
index d32e843ae2da9c18d16f336c32ba15cb418c3a46..aed00645b51763a2eff13f1d6c6e77d53584e90b 100644 (file)
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -32,10 +32,10 @@ SSL_CTX *ssl_ctx;
 void ssl_init() {
     SSL_METHOD *meth;
                
-    SSLeay_add_ssl_algorithms();
-    meth = SSLv2_client_method();
+    SSL_library_init();
     SSL_load_error_strings();
-    ssl_ctx = SSL_CTX_new(meth);
+    
+    ssl_ctx = SSL_CTX_new(SSLv23_client_method());
     if(ssl_ctx == NULL) {
        debug_print(_("SSL disabled\n"));
     } else {
@@ -44,9 +44,10 @@ void ssl_init() {
 }
 
 void ssl_done() {
-    if(ssl_ctx) {
-       SSL_CTX_free(ssl_ctx);
-    }
+    if(!ssl_ctx)
+       return;
+       
+    SSL_CTX_free(ssl_ctx);
 }
 
 gboolean ssl_init_socket(SockInfo *sockinfo) {
@@ -64,6 +65,7 @@ gboolean ssl_init_socket(SockInfo *sockinfo) {
 
        return FALSE;
     }
+
     SSL_set_fd(sockinfo->ssl, sockinfo->sock);
     if(SSL_connect(sockinfo->ssl) == -1) {
        log_warning(_("SSL connect failed\n"));