sync with 0.7.6cvs18
[claws.git] / src / imap.c
index 76319b792d494a5adc7ecfb32eb2f15be373fc43..752dd75a6844a4612f611f50572181bfd5bc64df 100644 (file)
@@ -112,16 +112,17 @@ static void imap_delete_all_cached_messages       (FolderItem     *item);
 #if USE_SSL
 static SockInfo *imap_open             (const gchar    *server,
                                         gushort         port,
-                                        gboolean        use_ssl);
+                                        SSLType         ssl_type);
 #else
 static SockInfo *imap_open             (const gchar    *server,
                                         gushort         port);
 #endif
 
 static SockInfo *imap_open_tunnel(const gchar *server,
-                                 const gchar *tunnelcmd);
+                                 const gchar *tunnelcmd,
+                                 SSLType ssl_type);
 
-static SockInfo *imap_init_sock(SockInfo *sock);
+static SockInfo *imap_init_sock(SockInfo *sock, SSLType ssl_type);
 
 static gint imap_set_message_flags     (IMAPSession    *session,
                                         guint32         first_uid,
@@ -183,6 +184,7 @@ static gint imap_cmd_login  (SockInfo       *sock,
                                 const gchar    *pass);
 static gint imap_cmd_logout    (SockInfo       *sock);
 static gint imap_cmd_noop      (SockInfo       *sock);
+static gint imap_cmd_starttls  (SockInfo       *sock);
 static gint imap_cmd_namespace (SockInfo       *sock,
                                 gchar         **ns_str);
 static gint imap_cmd_list      (SockInfo       *sock,
@@ -321,7 +323,8 @@ static IMAPSession *imap_session_get(Folder *folder)
 
 #if USE_SSL
        port = folder->account->set_imapport ? folder->account->imapport
-               : folder->account->ssl_imap ? IMAPS_PORT : IMAP4_PORT;
+               : folder->account->ssl_imap == SSL_TUNNEL
+               ? IMAPS_PORT : IMAP4_PORT;
 #else
        port = folder->account->set_imapport ? folder->account->imapport
                : IMAP4_PORT;
@@ -381,11 +384,11 @@ Session *imap_session_new(const PrefsAccount *account)
 
 #ifdef USE_SSL
        /* FIXME: IMAP over SSL only... */ 
-       gboolean use_ssl;
+       SSLType ssl_type;
 
        port = account->set_imapport ? account->imapport
                : account->ssl_imap ? IMAPS_PORT : IMAP4_PORT;
-       use_ssl = account->ssl_imap ? TRUE : FALSE;     
+       ssl_type = account->ssl_imap ? TRUE : FALSE;    
 #else
        port = account->set_imapport ? account->imapport
                : IMAP4_PORT;
@@ -394,7 +397,8 @@ Session *imap_session_new(const PrefsAccount *account)
        if (account->set_tunnelcmd) {
                log_message(_("creating tunneled IMAP4 connection\n"));
                if ((imap_sock = imap_open_tunnel(account->recv_server, 
-                                                 account->tunnelcmd)) == NULL)
+                                                 account->tunnelcmd,
+                                                 ssl_type)) == NULL)
                        return NULL;
        } else {
                g_return_val_if_fail(account->recv_server != NULL, NULL);
@@ -404,7 +408,7 @@ Session *imap_session_new(const PrefsAccount *account)
                
 #if USE_SSL
                if ((imap_sock = imap_open(account->recv_server, port,
-                                          use_ssl)) == NULL)
+                                          ssl_type)) == NULL)
 #else
                if ((imap_sock = imap_open(account->recv_server, port)) == NULL)
 #endif
@@ -1588,7 +1592,8 @@ static void imap_delete_all_cached_messages(FolderItem *item)
 
 
 static SockInfo *imap_open_tunnel(const gchar *server,
-                          const gchar *tunnelcmd)
+                          const gchar *tunnelcmd,
+                          SSLType ssl_type)
 {
        SockInfo *sock;
 
@@ -1597,13 +1602,13 @@ static SockInfo *imap_open_tunnel(const gchar *server,
                            server);
                return NULL;
 
-       return imap_init_sock(sock);
+       return imap_init_sock(sock, ssl_type);
 }
 
 
 #if USE_SSL
 static SockInfo *imap_open(const gchar *server, gushort port,
-                          gboolean use_ssl)
+                          SSLType ssl_type)
 #else
 static SockInfo *imap_open(const gchar *server, gushort port)
 #endif
@@ -1617,7 +1622,7 @@ static SockInfo *imap_open(const gchar *server, gushort port)
        }
 
 #if USE_SSL
-       if (use_ssl && !ssl_init_socket(sock)) {
+       if (ssl_type == SSL_TUNNEL && !ssl_init_socket(sock)) {
                log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
                            server, port);
                sock_close(sock);
@@ -1625,16 +1630,32 @@ static SockInfo *imap_open(const gchar *server, gushort port)
        }
 #endif
 
-       return imap_init_sock(sock);
+       return imap_init_sock(sock, ssl_type);
 }
 
 
-static SockInfo *imap_init_sock(SockInfo *sock)
+static SockInfo *imap_init_sock(SockInfo *sock, SSLType ssl_type)
 {
        imap_cmd_count = 0;
+#if USE_SSL
+       if (ssl_type == SSL_STARTTLS) {
+               gint ok;
+
+               ok = imap_cmd_starttls(sock);
+               if (ok != IMAP_SUCCESS) {
+                       log_warning(_("Can't start TLS session.\n"));
+                       sock_close(sock);
+                       return NULL;
+               }
+               if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1)) {
+                       sock_close(sock);
+                       return NULL;
+               }
+       }
+#endif
 
        if (imap_cmd_noop(sock) != IMAP_SUCCESS) {
-               log_warning(_("Can't establish IMAP4 session\n"));
+               log_warning(_("Can't establish IMAP4 session\n"));
                sock_close(sock);
                return NULL;
        }
@@ -2399,6 +2420,12 @@ static gint imap_cmd_noop(SockInfo *sock)
        return imap_cmd_ok(sock, NULL);
 }
 
+static gint imap_cmd_starttls(SockInfo *sock)
+{
+       imap_cmd_gen_send(sock, "STARTTLS");
+       return imap_cmd_ok(sock, NULL);
+}
+
 #define THROW(err) { ok = err; goto catch; }
 
 static gint imap_cmd_namespace(SockInfo *sock, gchar **ns_str)