+2001-07-10 [christoph]
+
+ * acconfig.h
+ * configure.in
+ added --enable-ssl
+ * src/md5.[ch]
+ renamed MD5_CTX to MD5_CTX_syl
+ conflicts with a struct in openssl
+ * src/inc.c
+ * src/main.[ch]
+ * src/prefs_account.[ch]
+ * src/socket.[ch]
+ SSL support for POP
+ * src/mainwindow.c
+ fixed compose with current account
+ broken by new compose button stuff
+
2001-07-09 [hoa]
* AUTHORS
/* Define if we use GPGME to support OpenPGP */
#undef USE_GPGME
+/* Define if we use GPGME to support OpenPGP */
+#undef USE_SSL
+
/* Define to `unsigned int' if <stddef.h> or <wchar.h> doesn't define. */
#undef wint_t
AM_PATH_GPGME(0.2.1, AC_DEFINE(USE_GPGME), [use_gpgme=no])
fi
+dnl Use OpenSSL for SSL connections
+AC_MSG_CHECKING([whether to use ssl])
+AC_ARG_ENABLE(ssl,
+ [ --enable-ssl Enable SSL support using OpenSSL [default=no]],
+ [ac_cv_enable_ssl=$enableval], [ac_cv_enable_ssl=no])
+if test $ac_cv_enable_ssl = yes; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+if test $ac_cv_enable_ssl = yes; then
+ AC_MSG_CHECKING([whether to openssl is available])
+ LIBS="$LIBS -lssl"
+ AC_TRY_LINK([
+#include <openssl/opensslv.h>
+], [ return(OPENSSL_VERSION_NUMBER); ],
+ [ AC_MSG_RESULT(yes)
+ AC_DEFINE(USE_SSL) ],
+ [ AC_MSG_RESULT(no)
+ LIBS="$ac_save_LIBS" ])
+fi
+
dnl Check for X-Face support
AC_ARG_ENABLE(compface,
[ --disable-compface Do not use compface (X-Face)],
GTK_SIGNAL_FUNC(inc_cancel), dialog);
gtk_signal_connect(GTK_OBJECT(progress->window), "delete_event",
GTK_SIGNAL_FUNC(gtk_true), NULL);
- manage_window_set_transient(GTK_WINDOW(progress->window));
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_set_transient(GTK_WINDOW(progress->window));
+ }
progress_dialog_set_value(progress, 0.0);
pass = input_dialog_with_invisible(_("Input password"),
message, NULL);
g_free(message);
- manage_window_focus_in(inc_dialog->mainwin->window,
- NULL, NULL);
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_focus_in(inc_dialog->mainwin->window,
+ NULL, NULL);
+ }
if (pass) {
pop3_state->ac_prefs->tmp_pass = g_strdup(pass);
pop3_state->pass = pass;
if (pop3_state->error_val == PS_AUTHFAIL) {
if(!prefs_common.noerrorpanel) {
- manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ }
alertpanel_error
(_("Authorization for %s on %s failed"),
pop3_state->user,
}
statusbar_pop_all();
- manage_window_focus_in(inc_dialog->mainwin->window, NULL, NULL);
-
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_focus_in(inc_dialog->mainwin->window, NULL, NULL);
+ }
+
folder_item_scan_foreach(pop3_state->folder_table);
folderview_update_item_foreach(pop3_state->folder_table);
atm->num = POP3_GREETING_RECV;
server = pop3_state->ac_prefs->recv_server;
+#if USE_SSL
+ port = pop3_state->ac_prefs->set_popport ?
+ pop3_state->ac_prefs->popport : (pop3_state->ac_prefs->pop_ssl ? 995 : 110);
+#else
port = pop3_state->ac_prefs->set_popport ?
pop3_state->ac_prefs->popport : 110;
+#endif
buf = g_strdup_printf(_("Connecting to POP3 server: %s ..."), server);
log_message("%s\n", buf);
log_warning(_("Can't connect to POP3 server: %s:%d\n"),
server, port);
if(!prefs_common.noerrorpanel) {
- manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ }
alertpanel_error(_("Can't connect to POP3 server: %s:%d"),
server, port);
manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL);
pop3_state->sockinfo = sockinfo;
atm->help_sock = sockinfo;
+#ifdef USE_SSL
+ if(pop3_state->ac_prefs->pop_ssl) {
+ X509 *server_cert;
+
+ if(ssl_ctx == NULL) {
+ log_warning(_("SSL not available\n"));
+
+ pop3_automaton_terminate(NULL, atm);
+ automaton_destroy(atm);
+
+ return INC_ERROR;
+ }
+
+ sockinfo->ssl = SSL_new(ssl_ctx);
+ if(sockinfo->ssl == NULL) {
+ log_warning(_("Error creating ssl context\n"));
+
+ pop3_automaton_terminate(NULL, atm);
+ automaton_destroy(atm);
+
+ return INC_ERROR;
+ }
+ SSL_set_fd(sockinfo->ssl, sockinfo->sock);
+ if(SSL_connect(sockinfo->ssl) == -1) {
+ log_warning(_("SSL connect failed\n"));
+
+ pop3_automaton_terminate(NULL, atm);
+ automaton_destroy(atm);
+
+ return INC_ERROR;
+ }
+
+ /* Get the cipher */
+
+ log_print(_("SSL connection using %s\n"), SSL_get_cipher(sockinfo->ssl));
+
+ /* Get server's certificate (note: beware of dynamic allocation) */
+
+ if((server_cert = SSL_get_peer_certificate(sockinfo->ssl)) != NULL) {
+ char *str;
+
+ log_print(_("Server certificate:\n"));
+
+ if((str = X509_NAME_oneline(X509_get_subject_name (server_cert),0,0)) != NULL) {
+ log_print(_(" Subject: %s\n"), str);
+ free(str);
+ }
+
+ if((str = X509_NAME_oneline(X509_get_issuer_name (server_cert),0,0)) != NULL) {
+ log_print(_(" Issuer: %s\n"), str);
+ free(str);
+ }
+
+ X509_free(server_cert);
+ }
+ } else {
+ sockinfo->ssl = NULL;
+ }
+#endif
+
recv_set_ui_func(inc_pop3_recv_func, session);
#if USE_THREADS
pthread_join(sockinfo->connect_thr, NULL);
*/
#endif
+
+#if USE_SSL
+ if(sockinfo->ssl) {
+ SSL_free(sockinfo->ssl);
+ }
+#endif
+
automaton_destroy(atm);
return pop3_state->inc_state;
log_warning(_("Can't connect to POP3 server: %s:%d\n"),
sockinfo->hostname, sockinfo->port);
if(!prefs_common.noerrorpanel) {
- manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ if((prefs_common.receive_dialog == RECVDIALOG_ALWAYS) ||
+ ((prefs_common.receive_dialog == RECVDIALOG_WINDOW_ACTIVE) && focus_window)) {
+ manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL);
+ }
alertpanel_error(_("Can't connect to POP3 server: %s:%d"),
sockinfo->hostname, sockinfo->port);
manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL);
static gint lock_socket = -1;
static gint lock_socket_tag = 0;
+#if USE_SSL
+SSL_CTX *ssl_ctx;
+#endif
+
static struct Cmd {
gboolean receive;
gboolean receive_all;
gpgme_register_idle(idle_function_for_gpgme);
#endif
+#if USE_SSL
+ {
+ SSL_METHOD *meth;
+
+ SSLeay_add_ssl_algorithms();
+ meth = SSLv2_client_method();
+ SSL_load_error_strings();
+ ssl_ctx = SSL_CTX_new(meth);
+ if(ssl_ctx == NULL) {
+ debug_print(_("SSL disabled\n"));
+ } else {
+ debug_print(_("SSL loaded: \n"));
+ }
+ }
+#endif
+
prefs_common_save_config();
prefs_filter_read_config();
prefs_filter_write_config();
gtk_main();
+#if USE_SSL
+ if(ssl_ctx) {
+ SSL_CTX_free(ssl_ctx);
+ }
+#endif
+
return 0;
}
#include <glib.h>
#include <gtk/gtkwidget.h>
+#ifdef USE_SSL
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
+
extern gchar *prog_version;
extern gchar *startup_dir;
extern gboolean debug_mode;
+#ifdef USE_SSL
+extern SSL_CTX *ssl_ctx;
+#endif
+
void app_will_exit (GtkWidget *widget, gpointer data);
#endif /* __MAIN_H__ */
}
}
+ if(cur_account && (cur_account->protocol != A_NNTP)) {
+ compose_new(cur_account);
+ return;
+ }
+
list = account_get_list();
for(cur = list ; cur != NULL ; cur = g_list_next(cur)) {
ac = (PrefsAccount *) cur->data;
md5_hex_digest(char *hexdigest, const unsigned char *s)
{
int i;
- MD5_CTX context;
+ MD5_CTX_syl context;
unsigned char digest[16];
md5_init(&context);
const unsigned char* text, int text_len,
const unsigned char* key, int key_len)
{
- MD5_CTX context;
+ MD5_CTX_syl context;
unsigned char k_ipad[64]; /* inner padding -
* key XORd with ipad
*/
memset(k_opad, 0, sizeof k_opad);
if (key_len > 64) {
/* if key is longer than 64 bytes reset it to key=MD5(key) */
- MD5_CTX tctx;
+ MD5_CTX_syl tctx;
md5_init(&tctx);
md5_update(&tctx, key, key_len);
int finalized;
} MD5_CONTEXT;
-typedef MD5_CONTEXT MD5_CTX;
+typedef MD5_CONTEXT MD5_CTX_syl;
void md5_init(MD5_CONTEXT *ctx);
void md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen);
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;
&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},
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;
PACK_PORT_ENTRY (hbox_popport, entry_popport);
SET_TOGGLE_SENSITIVITY (checkbtn_popport, entry_popport);
+#ifdef USE_SSL
+ PACK_CHECK_BUTTON (vbox2, checkbtn_popssl, _("Use SSL to connect to POP server"));
+#endif
+
PACK_HBOX (hbox_imapport);
PACK_CHECK_BUTTON (hbox_imapport, checkbtn_imapport,
_("Specify IMAP4 port"));
advanced.popport_hbox = hbox_popport;
advanced.popport_chkbtn = checkbtn_popport;
advanced.popport_entry = entry_popport;
+#ifdef USE_SSL
+ advanced.popssl_chkbtn = checkbtn_popssl;
+#endif
advanced.imapport_hbox = hbox_imapport;
advanced.imapport_chkbtn = checkbtn_imapport;
advanced.imapport_entry = entry_imapport;
gushort smtpport;
gboolean set_popport;
gushort popport;
+#if USE_SSL
+ gboolean pop_ssl;
+#endif
gboolean set_imapport;
gushort imapport;
gboolean set_nntpport;
{
g_return_val_if_fail(sock != NULL, -1);
+#if USE_SSL
+ if(sock->ssl) {
+ return ssl_read(sock->ssl, buf, len);
+ }
+#endif
return fd_read(sock->sock, buf, len);
}
return read(fd, buf, len);
}
+#ifdef USE_SSL
+gint ssl_read(SSL *ssl, gchar *buf, gint len)
+{
+ return SSL_read(ssl, buf, len);
+}
+#endif
+
gint sock_write(SockInfo *sock, const gchar *buf, gint len)
{
g_return_val_if_fail(sock != NULL, -1);
+#if USE_SSL
+ if(sock->ssl) {
+ return ssl_write(sock->ssl, buf, len);
+ }
+#endif
return fd_write(sock->sock, buf, len);
}
return wrlen;
}
+#ifdef USE_SSL
+gint ssl_write(SSL *ssl, const gchar *buf, gint len)
+{
+ gint n, wrlen = 0;
+
+ while (len) {
+ n = SSL_write(ssl, buf, len);
+ if (n <= 0)
+ return -1;
+ len -= n;
+ wrlen += n;
+ buf += n;
+ }
+
+ return wrlen;
+}
+#endif
+
gint fd_gets(gint fd, gchar *buf, gint len)
{
gchar *newline, *bp = buf;
return bp - buf;
}
+#if USE_SSL
+gint ssl_gets(SSL *ssl, gchar *buf, gint len)
+{
+ gchar *buf2 = buf;
+ gboolean newline = FALSE;
+ gint n, count = 0;
+
+ if (--len < 1)
+ return -1;
+ while(len > 0 && !newline) {
+ *buf2 = '\0';
+ if((n = SSL_read(ssl, buf2, 1)) < 0)
+ return -1;
+ if(*buf2 == '\n')
+ newline = TRUE;
+ buf2 += n;
+ count += n;
+ }
+
+ *buf2 = '\0';
+ return n;
+}
+#endif
+
gint sock_gets(SockInfo *sock, gchar *buf, gint len)
{
g_return_val_if_fail(sock != NULL, -1);
+#if USE_SSL
+ if(sock->ssl) {
+ return ssl_gets(sock->ssl, buf, len);
+ }
+#endif
return fd_gets(sock->sock, buf, len);
}
return str;
}
+#if USE_SSL
+gchar *ssl_getline(SSL *ssl)
+{
+ gchar buf[BUFFSIZE];
+ gchar *str = NULL;
+ gint len;
+ gulong size = 1;
+
+ while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) {
+ size += len;
+ if (!str)
+ str = g_strdup(buf);
+ else {
+ str = g_realloc(str, size);
+ strcat(str, buf);
+ }
+ if (buf[len - 1] == '\n')
+ break;
+ }
+
+ return str;
+}
+#endif
+
gchar *sock_getline(SockInfo *sock)
{
g_return_val_if_fail(sock != NULL, NULL);
+#if USE_SSL
+ if(sock->ssl) {
+ return ssl_getline(sock->ssl);
+ }
+#endif
return fd_getline(sock->sock);
}
# include <pthread.h>
#endif
+#if USE_SSL
+# include <openssl/crypto.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+# include <openssl/ssl.h>
+# include <openssl/err.h>
+#endif
+
typedef struct _SockInfo SockInfo;
typedef enum
pthread_t connect_thr;
pthread_mutex_t mutex;
#endif
+#if USE_SSL
+ SSL *ssl;
+#endif
};
gint sock_set_nonblocking_mode (SockInfo *sock, gboolean nonblock);