diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2001-05-08 04:33:25 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2001-05-08 04:33:25 +0800 |
commit | 416d8fa6cd84e6b25886c1c2fcbf2b0dbce58b7f (patch) | |
tree | ed169f150b00a9edcd0c03ba642f166a62919d21 /camel/camel-tcp-stream-openssl.c | |
parent | fe36d75cf353522bc31362bd9b8800470fa511b3 (diff) | |
download | gsoc2013-evolution-416d8fa6cd84e6b25886c1c2fcbf2b0dbce58b7f.tar.gz gsoc2013-evolution-416d8fa6cd84e6b25886c1c2fcbf2b0dbce58b7f.tar.zst gsoc2013-evolution-416d8fa6cd84e6b25886c1c2fcbf2b0dbce58b7f.zip |
Add support for using OpenSSL.
2001-05-04 Jeffrey Stedfast <fejj@ximian.com>
* providers/smtp/camel-smtp-transport.c (connect_to_server): Add
support for using OpenSSL.
* camel-remote-store.c (remote_connect): Add support for using the
OpenSSL implementation.
* camel-tcp-stream-ssl.c (ssl_bad_cert): Hmmmm, don't pass in a
NULL as the last argument to alert_user - prototype doesn't take
that argument anymore?
* camel-tcp-stream-openssl.c (camel_tcp_stream_openssl_finalize):
(ssl_verify): Use a global hash table to try and lookup the
CamelTcpStreamOpenSSL object given the ssl context since OpenSSL
doesn't think one needs to pass data around, we should all be
living in a world of global variables, duh!
svn path=/trunk/; revision=9697
Diffstat (limited to 'camel/camel-tcp-stream-openssl.c')
-rw-r--r-- | camel/camel-tcp-stream-openssl.c | 82 |
1 files changed, 60 insertions, 22 deletions
diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c index c59705ae8a..0312e65b44 100644 --- a/camel/camel-tcp-stream-openssl.c +++ b/camel/camel-tcp-stream-openssl.c @@ -25,7 +25,11 @@ #endif #ifdef HAVE_OPENSSL -#include <openssl/openssl.h> + +#include "camel-tcp-stream-openssl.h" + +#include <openssl/ssl.h> +#include <openssl/x509.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> @@ -33,11 +37,25 @@ #include <fcntl.h> #include <errno.h> #include <string.h> -#include "camel-tcp-stream-openssl.h" +#include "camel-session.h" +#include "camel-service.h" #include "camel-operation.h" +#ifdef ENABLE_THREADS +#include <pthread.h> +#endif static CamelTcpStreamClass *parent_class = NULL; +static GHashTable *openssl_table = NULL; +#ifdef ENABLE_THREADS +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +#define OPENSSL_TABLE_LOCK() pthread_mutex_lock (&lock) +#define OPENSSL_TABLE_UNLOCK() pthread_mutex_unlock (&lock) +#else +#define OPENSSL_TABLE_LOCK +#define OPENSSL_TABLE_UNLOCK +#endif + /* Returns the class for a CamelTcpStreamOpenSSL */ #define CTSR_CLASS(so) CAMEL_TCP_STREAM_OPENSSL_CLASS (CAMEL_OBJECT_GET_CLASS (so)) @@ -98,8 +116,16 @@ camel_tcp_stream_openssl_finalize (CamelObject *object) if (stream->priv->ssl) { SSL_shutdown (stream->priv->ssl); - if (stream->priv->ssl->ctx) + if (stream->priv->ssl->ctx) { + OPENSSL_TABLE_LOCK (); + g_hash_table_remove (openssl_table, stream->priv->ssl->ctx); + if (g_hash_table_size (openssl_table) == 0) { + g_hash_table_destroy (openssl_table); + openssl_table = NULL; + } + OPENSSL_TABLE_UNLOCK (); SSL_CTX_free (stream->priv->ssl->ctx); + } SSL_free (stream->priv->ssl); } @@ -376,30 +402,35 @@ socket_connect (struct hostent *h, int port) static int ssl_verify (int ok, X509_STORE_CTX *ctx) { - char *str, buf[256]; + CamelTcpStreamOpenSSL *stream; X509 *cert; int err; + OPENSSL_TABLE_LOCK (); + stream = CAMEL_TCP_STREAM_OPENSSL (g_hash_table_lookup (openssl_table, ctx)); + OPENSSL_TABLE_UNLOCK (); + cert = X509_STORE_CTX_get_current_cert (ctx); err = X509_STORE_CTX_get_error (ctx); - str = X509_NAME_oneline (X509_get_subject_name (cert), buf, 256); - if (str) { - if (ok) - d(fprintf (stderr, "CamelTcpStreamSSL: depth=%d %s\n", ctx->error_depth, buf)); - else - d(fprintf (stderr, "CamelTcpStreamSSL: depth=%d error=%d %s\n", - ctx->error_depth, err, buf)); - } - - if (!ok) { - switch (err) { - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - /* FIXME: get user's response */ - ok = 1; - } + if (!ok && stream) { + CamelService *service = stream->priv->service; + char *prompt, *cert_str; + char buf[257]; + +#define GET_STRING(name) X509_NAME_oneline(name, buf, 256) + + cert_str = g_strdup_printf (_("Issuer: %s\n" + "Subject: %s"), + GET_STRING (X509_get_issuer_name (cert)), + GET_STRING (X509_get_subject_name (cert))); + + prompt = g_strdup_printf (_("Bad certificate from %s:\n\n%s\n\n" + "Do you wish to accept anyway?"), + service->url->host, cert_str); + + ok = camel_session_alert_user (service->session, CAMEL_SESSION_ALERT_WARNING, prompt, TRUE); + g_free (prompt); } return ok; @@ -445,13 +476,20 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port) if (fd == -1) return -1; - ssl = open_ssl_connection (stream->priv->service, sockfd); + ssl = open_ssl_connection (openssl->priv->service, fd); if (!ssl) return -1; openssl->priv->sockfd = fd; openssl->priv->ssl = ssl; + OPENSSL_TABLE_LOCK (); + if (!openssl_table) + openssl_table = g_hash_table_new (g_direct_hash, g_direct_equal); + + g_hash_table_insert (openssl_table, ssl->ctx, openssl); + OPENSSL_TABLE_UNLOCK (); + return 0; } |