From: Christoph Hohmann Date: Fri, 27 Jul 2001 17:24:14 +0000 (+0000) Subject: SMTP over SSL (untested, feedback requested) X-Git-Tag: post_folder_chmod~12 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=2e51812742c40a85eeb1fa7f2cdf1d7b865524aa;hp=19a99f3dd3d13ee0488481ffbf732b40d83cc232 SMTP over SSL (untested, feedback requested) IMAP over SSL --- diff --git a/ChangeLog.claws b/ChangeLog.claws index ba43fded6..c5ba23224 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -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 diff --git a/src/imap.c b/src/imap.c index 02b99ad2b..bb0494fa3 100644 --- a/src/imap.c +++ b/src/imap.c @@ -41,8 +41,12 @@ #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) { diff --git a/src/imap.h b/src/imap.h index 958ad8476..96a7716ef 100644 --- a/src/imap.h +++ b/src/imap.h @@ -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); diff --git a/src/prefs_account.c b/src/prefs_account.c index 0ec036596..e79d9a823 100644 --- a/src/prefs_account.c +++ b/src/prefs_account.c @@ -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; } diff --git a/src/prefs_account.h b/src/prefs_account.h index 45ca63821..8d8f364c2 100644 --- a/src/prefs_account.h +++ b/src/prefs_account.h @@ -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; diff --git a/src/send.c b/src/send.c index ad182fda4..ea7447852 100644 --- a/src/send.c +++ b/src/send.c @@ -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); diff --git a/src/ssl.c b/src/ssl.c index d32e843ae..aed00645b 100644 --- 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"));