diff options
-rw-r--r-- | camel/ChangeLog | 16 | ||||
-rw-r--r-- | camel/camel-tcp-stream-openssl.c | 91 | ||||
-rw-r--r-- | camel/camel-tcp-stream-openssl.h | 8 | ||||
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 8 | ||||
-rw-r--r-- | camel/camel-tcp-stream-ssl.c | 79 | ||||
-rw-r--r-- | camel/camel-tcp-stream-ssl.h | 10 | ||||
-rw-r--r-- | camel/camel-tcp-stream.c | 27 | ||||
-rw-r--r-- | camel/camel-tcp-stream.h | 5 | ||||
-rw-r--r-- | camel/providers/smtp/camel-smtp-transport.c | 8 |
9 files changed, 170 insertions, 82 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 617e1b44b9..58e58e416b 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,19 @@ +2001-03-16 Jeffrey Stedfast <fejj@ximian.com> + + * camel-tcp-stream-ssl.c (ssl_bad_cert): Print info about the + issuer of the certificate. + + * providers/smtp/camel-smtp-transport.c (smtp_connect): Use + camel_tcp_stream_get_socket(). + + * camel-tcp-stream-openssl.c (stream_get_socket): Implemented. + + * camel-tcp-stream-ssl.c (stream_get_socket): Implemented. + + * camel-tcp-stream-raw.c (stream_get_socket): Implemented. + + * camel-tcp-stream.c (camel_tcp_stream_get_socket): New function. + 2001-03-16 Kjartan Maraas <kmaraas@gnome.org> * providers/pop3/camel-pop3-folder.c: Added #include <config.h> diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c index d0a6d3f95b..1830c8dab6 100644 --- a/camel/camel-tcp-stream-openssl.c +++ b/camel/camel-tcp-stream-openssl.c @@ -26,6 +26,7 @@ #ifdef HAVE_OPENSSL #include "camel-tcp-stream-openssl.h" #include "camel-operation.h" +#include <openssl/openssl.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> @@ -47,6 +48,12 @@ static int stream_close (CamelStream *stream); static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port); static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data); +static gpointer stream_get_socket (CamelTcpStream *stream); + +struct _CamelTcpStreamOpenSSLPrivate { + int sockfd; + SSL *ssl; +}; static void camel_tcp_stream_openssl_class_init (CamelTcpStreamOpenSSLClass *camel_tcp_stream_openssl_class) @@ -67,6 +74,7 @@ camel_tcp_stream_openssl_class_init (CamelTcpStreamOpenSSLClass *camel_tcp_strea camel_tcp_stream_class->connect = stream_connect; camel_tcp_stream_class->getsockopt = stream_getsockopt; camel_tcp_stream_class->setsockopt = stream_setsockopt; + camel_tcp_stream_class->get_socket = stream_get_socket; } static void @@ -74,8 +82,9 @@ camel_tcp_stream_openssl_init (gpointer object, gpointer klass) { CamelTcpStreamOpenSSL *stream = CAMEL_TCP_STREAM_OPENSSL (object); - stream->sockfd = -1; - stream->ssl = NULL; + stream->priv = g_new (struct _CamelTcpStreamOpenSSLPrivate, 1); + stream->priv->sockfd = -1; + stream->priv->ssl = NULL; } static void @@ -83,17 +92,19 @@ camel_tcp_stream_openssl_finalize (CamelObject *object) { CamelTcpStreamOpenSSL *stream = CAMEL_TCP_STREAM_OPENSSL (object); - if (stream->ssl) { - SSL_shutdown (stream->ssl); + if (stream->priv->ssl) { + SSL_shutdown (stream->priv->ssl); - if (stream->ssl->ctx) - SSL_CTX_free (stream->ssl->ctx); + if (stream->priv->ssl->ctx) + SSL_CTX_free (stream->priv->ssl->ctx); - SSL_free (stream->ssl); + SSL_free (stream->priv->ssl); } - if (stream->sockfd != -1) - close (stream->sockfd); + if (stream->priv->sockfd != -1) + close (stream->priv->sockfd); + + g_free (stream->priv); } @@ -147,29 +158,29 @@ stream_read (CamelStream *stream, char *buffer, size_t n) cancel_fd = camel_operation_cancel_fd (NULL); if (cancel_fd == -1) { do { - nread = SSL_read (tcp_stream_openssl->ssl, buffer, n); + nread = SSL_read (tcp_stream_openssl->priv->ssl, buffer, n); } while (nread == -1 && errno == EINTR); } else { int flags, fdmax; fd_set rdset; - flags = fcntl (tcp_stream_openssl->sockfd, F_GETFL); - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags | O_NONBLOCK); + flags = fcntl (tcp_stream_openssl->priv->sockfd, F_GETFL); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags | O_NONBLOCK); FD_ZERO (&rdset); - FD_SET (tcp_stream_openssl->sockfd, &rdset); + FD_SET (tcp_stream_openssl->priv->sockfd, &rdset); FD_SET (cancel_fd, &rdset); - fdmax = MAX (tcp_stream_openssl->sockfd, cancel_fd) + 1; + fdmax = MAX (tcp_stream_openssl->priv->sockfd, cancel_fd) + 1; select (fdmax, &rdset, 0, 0, NULL); if (FD_ISSET (cancel_fd, &rdset)) { - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); errno = EINTR; return -1; } - nread = SSL_read (tcp_stream_openssl->ssl, buffer, n); - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags); + nread = SSL_read (tcp_stream_openssl->priv->ssl, buffer, n); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); } return nread; @@ -190,35 +201,35 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) cancel_fd = camel_operation_cancel_fd (NULL); if (cancel_fd == -1) { do { - written = SSL_write (tcp_stream_openssl->ssl, buffer, n); + written = SSL_write (tcp_stream_openssl->priv->ssl, buffer, n); } while (written == -1 && errno == EINTR); } else { fd_set rdset, wrset; int flags, fdmax; - flags = fcntl (tcp_stream_openssl->sockfd, F_GETFL); - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags | O_NONBLOCK); + flags = fcntl (tcp_stream_openssl->priv->sockfd, F_GETFL); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags | O_NONBLOCK); - fdmax = MAX (tcp_stream_openssl->sockfd, cancel_fd) + 1; + fdmax = MAX (tcp_stream_openssl->priv->sockfd, cancel_fd) + 1; do { FD_ZERO (&rdset); FD_ZERO (&wrset); - FD_SET (tcp_stream_openssl->sockfd, &wrset); + FD_SET (tcp_stream_openssl->priv->sockfd, &wrset); FD_SET (cancel_fd, &rdset); select (fdmax, &rdset, &wrset, 0, NULL); if (FD_ISSET (cancel_fd, &rdset)) { - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); errno = EINTR; return -1; } - w = SSL_write (tcp_stream_openssl->ssl, buffer + written, n - written); + w = SSL_write (tcp_stream_openssl->priv->ssl, buffer + written, n - written); if (w > 0) written += w; } while (w != -1 && written < n); - fcntl (tcp_stream_openssl->sockfd, F_SETFL, flags); + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); } return written; @@ -227,7 +238,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) static int stream_flush (CamelStream *stream) { - return fsync (((CamelTcpStreamOpenSSL *)stream)->sockfd); + return fsync (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd); } @@ -247,13 +258,13 @@ close_ssl_connection (SSL *ssl) static int stream_close (CamelStream *stream) { - close_ssl_connection (((CamelTcpStreamOpenSSL *)stream)->ssl); - ((CamelTcpStreamOpenSSL *)stream)->ssl = NULL; + close_ssl_connection (((CamelTcpStreamOpenSSL *)stream)->priv->ssl); + ((CamelTcpStreamOpenSSL *)stream)->priv->ssl = NULL; - if (close (((CamelTcpStreamOpenSSL *)stream)->sockfd) == -1) + if (close (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd) == -1) return -1; - ((CamelTcpStreamOpenSSL *)stream)->sockfd = -1; + ((CamelTcpStreamOpenSSL *)stream)->priv->sockfd = -1; return 0; } @@ -424,8 +435,8 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port) if (!ssl) return -1; - openssl->sockfd = fd; - openssl->ssl = ssl; + openssl->priv->sockfd = fd; + openssl->priv->ssl = ssl; return 0; } @@ -481,7 +492,7 @@ stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data) if (data->option == CAMEL_SOCKOPT_NONBLOCKING) { int flags; - flags = fcntl (((CamelTcpStreamOpenSSL *)stream)->sockfd, F_GETFL); + flags = fcntl (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd, F_GETFL); if (flags == -1) return -1; @@ -490,7 +501,7 @@ stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data) return 0; } - return getsockopt (((CamelTcpStreamOpenSSL *)stream)->sockfd, + return getsockopt (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd, get_sockopt_level (data), optname, (void *) &data->value, @@ -508,24 +519,30 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data) if (data->option == CAMEL_SOCKOPT_NONBLOCKING) { int flags, set; - flags = fcntl (((CamelTcpStreamOpenSSL *)stream)->sockfd, F_GETFL); + flags = fcntl (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd, F_GETFL); if (flags == -1) return -1; set = data->value.non_blocking ? 1 : 0; flags = (flags & ~O_NONBLOCK) | (set & O_NONBLOCK); - if (fcntl (((CamelTcpStreamOpenSSL *)stream)->sockfd, F_SETFL, flags) == -1) + if (fcntl (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd, F_SETFL, flags) == -1) return -1; return 0; } - return setsockopt (((CamelTcpStreamOpenSSL *)stream)->sockfd, + return setsockopt (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd, get_sockopt_level (data), optname, (void *) &data->value, sizeof (data->value)); } +static gpointer +stream_get_socket (CamelTcpStream *stream) +{ + return GINT_TO_POINTER (CAMEL_TCP_STREAM_OPENSSL (stream)->priv->sockfd); +} + #endif /* HAVE_OPENSSL */ diff --git a/camel/camel-tcp-stream-openssl.h b/camel/camel-tcp-stream-openssl.h index 8424019968..0103332c3f 100644 --- a/camel/camel-tcp-stream-openssl.h +++ b/camel/camel-tcp-stream-openssl.h @@ -30,10 +30,7 @@ extern "C" { #pragma } #endif /* __cplusplus */ -#ifdef HAVE_OPENSSL - #include <camel/camel-tcp-stream.h> -#include <openssl/ssl.h> #define CAMEL_TCP_STREAM_OPENSSL_TYPE (camel_tcp_stream_openssl_get_type ()) #define CAMEL_TCP_STREAM_OPENSSL(obj) (CAMEL_CHECK_CAST((obj), CAMEL_TCP_STREAM_OPENSSL_TYPE, CamelTcpStreamOpenSSL)) @@ -44,8 +41,7 @@ struct _CamelTcpStreamOpenSSL { CamelTcpStream parent_object; - int sockfd; - SSL *ssl; + struct _CamelTcpStreamOpenSSLPrivate *priv; }; typedef struct { @@ -61,8 +57,6 @@ CamelType camel_tcp_stream_openssl_get_type (void); /* public methods */ CamelStream *camel_tcp_stream_openssl_new (void); -#endif /* HAVE_OPENSSL */ - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index 2580f1a7e5..59e09080e9 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -45,6 +45,7 @@ static int stream_close (CamelStream *stream); static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port); static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data); +static gpointer stream_get_socket (CamelTcpStream *stream); static void camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_class) @@ -65,6 +66,7 @@ camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_cl camel_tcp_stream_class->connect = stream_connect; camel_tcp_stream_class->getsockopt = stream_getsockopt; camel_tcp_stream_class->setsockopt = stream_setsockopt; + camel_tcp_stream_class->get_socket = stream_get_socket; } static void @@ -433,3 +435,9 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data) (void *) &data->value, sizeof (data->value)); } + +static gpointer +stream_get_socket (CamelTcpStream *stream) +{ + return GINT_TO_POINTER (CAMEL_TCP_STREAM_RAW (stream)->sockfd); +} diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c index 332234291c..8aa4080660 100644 --- a/camel/camel-tcp-stream-ssl.c +++ b/camel/camel-tcp-stream-ssl.c @@ -32,6 +32,7 @@ #include <fcntl.h> #include <errno.h> #include <string.h> + #include <nspr.h> #include <prio.h> #include <prerror.h> @@ -52,7 +53,14 @@ static int stream_close (CamelStream *stream); static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port); static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data); +static gpointer stream_get_socket (CamelTcpStream *stream); +struct _CamelTcpStreamSSLPrivate { + PRFileDesc *sockfd; + + CamelService *service; + char *expected_host; +}; static void camel_tcp_stream_ssl_class_init (CamelTcpStreamSSLClass *camel_tcp_stream_ssl_class) @@ -73,6 +81,7 @@ camel_tcp_stream_ssl_class_init (CamelTcpStreamSSLClass *camel_tcp_stream_ssl_cl camel_tcp_stream_class->connect = stream_connect; camel_tcp_stream_class->getsockopt = stream_getsockopt; camel_tcp_stream_class->setsockopt = stream_setsockopt; + camel_tcp_stream_class->get_socket = stream_get_socket; } static void @@ -80,9 +89,7 @@ camel_tcp_stream_ssl_init (gpointer object, gpointer klass) { CamelTcpStreamSSL *stream = CAMEL_TCP_STREAM_SSL (object); - stream->sockfd = NULL; - stream->service = NULL; - stream->expected_host = NULL; + stream->priv = g_new0 (struct _CamelTcpStreamSSLPrivate, 1); } static void @@ -90,10 +97,12 @@ camel_tcp_stream_ssl_finalize (CamelObject *object) { CamelTcpStreamSSL *stream = CAMEL_TCP_STREAM_SSL (object); - if (stream->sockfd != NULL) - PR_Close (stream->sockfd); + if (stream->priv->sockfd != NULL) + PR_Close (stream->priv->sockfd); - g_free (stream->expected_host); + g_free (stream->priv->expected_host); + + g_free (stream->priv); } @@ -134,8 +143,8 @@ camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host) stream = CAMEL_TCP_STREAM_SSL (camel_object_new (camel_tcp_stream_ssl_get_type ())); - stream->service = service; - stream->expected_host = g_strdup (expected_host); + stream->priv->service = service; + stream->priv->expected_host = g_strdup (expected_host); return CAMEL_STREAM (stream); } @@ -164,7 +173,7 @@ stream_read (CamelStream *stream, char *buffer, size_t n) ssize_t nread; do { - nread = PR_Read (tcp_stream_ssl->sockfd, buffer, n); + nread = PR_Read (tcp_stream_ssl->priv->sockfd, buffer, n); } while (nread == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR); if (nread == -1) @@ -180,7 +189,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) ssize_t written = 0; do { - written = PR_Write (tcp_stream_ssl->sockfd, buffer, n); + written = PR_Write (tcp_stream_ssl->priv->sockfd, buffer, n); } while (written == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR); if (written == -1) @@ -192,16 +201,16 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) static int stream_flush (CamelStream *stream) { - return PR_Sync (((CamelTcpStreamSSL *)stream)->sockfd); + return PR_Sync (((CamelTcpStreamSSL *)stream)->priv->sockfd); } static int stream_close (CamelStream *stream) { - if (PR_Close (((CamelTcpStreamSSL *)stream)->sockfd) == PR_FAILURE) + if (PR_Close (((CamelTcpStreamSSL *)stream)->priv->sockfd) == PR_FAILURE) return -1; - ((CamelTcpStreamSSL *)stream)->sockfd = NULL; + ((CamelTcpStreamSSL *)stream)->priv->sockfd = NULL; return 0; } @@ -322,8 +331,9 @@ ssl_auth_cert (void *data, PRFileDesc *sockfd, PRBool checksig, PRBool is_server static SECStatus ssl_bad_cert (void *data, PRFileDesc *sockfd) { + CERTCertificate *cert; CamelService *service; - char *prompt, *err; + char *prompt, *cert_str; gpointer accept; PRUint32 len; @@ -332,14 +342,27 @@ ssl_bad_cert (void *data, PRFileDesc *sockfd) service = CAMEL_SERVICE (data); - len = PR_GetErrorTextLength (); - err = g_malloc0 (len + 1); - PR_GetErrorText (err); + cert = SSL_PeerCertificate (sockfd); + + cert_str = g_strdup_printf (_("EMail: %s\n" + "Common Name: %s\n" + "Organization Unit: %s\n" + "Organization: %s\n" + "Locality: %s\n" + "State: %s\n" + "Country: %s"), + cert->emailAddr ? cert->emailAddr : "", + CERT_GetCommonName (&cert->issuer) ? CERT_GetCommonName (&cert->issuer) : "", + CERT_GetOrgUnitName (&cert->issuer) ? CERT_GetOrgUnitName (&cert->issuer) : "", + CERT_GetOrgName (&cert->issuer) ? CERT_GetOrgName (&cert->issuer) : "", + CERT_GetLocalityName (&cert->issuer) ? CERT_GetLocalityName (&cert->issuer) : "", + CERT_GetStateName (&cert->issuer) ? CERT_GetStateName (&cert->issuer) : "", + CERT_GetCountryName (&cert->issuer) ? CERT_GetCountryName (&cert->issuer) : ""); /* construct our user prompt */ - prompt = g_strdup_printf (_("Bad certificate from %s:%s\n\nDo you wish to accept anyway?"), - service->url->host, err); - g_free (err); + prompt = g_strdup_printf (_("Bad certificate from %s:\n\n%s\n\nDo you wish to accept anyway?"), + service->url->host, cert_str); + g_free (cert_str); /* query the user to find out if we want to accept this certificate */ accept = camel_session_query_authenticator (service->session, CAMEL_AUTHENTICATOR_ACCEPT, @@ -372,7 +395,7 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port) fd = PR_OpenTCPSocket (host->h_addrtype); ssl_fd = SSL_ImportFD (NULL, fd); - SSL_SetURL (ssl_fd, ssl->expected_host); + SSL_SetURL (ssl_fd, ssl->priv->expected_host); if (ssl_fd == NULL || PR_Connect (ssl_fd, &netaddr, timeout) == PR_FAILURE) { if (ssl_fd != NULL) @@ -383,9 +406,9 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port) /*SSL_GetClientAuthDataHook (sslSocket, ssl_get_client_auth, (void *)certNickname);*/ /*SSL_AuthCertificateHook (ssl_fd, ssl_auth_cert, (void *) CERT_GetDefaultCertDB ());*/ - SSL_BadCertHook (ssl_fd, ssl_bad_cert, ssl->service); + SSL_BadCertHook (ssl_fd, ssl_bad_cert, ssl->priv->service); - ssl->sockfd = ssl_fd; + ssl->priv->sockfd = ssl_fd; return 0; } @@ -399,7 +422,7 @@ stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data) memset ((void *) &sodata, 0, sizeof (sodata)); memcpy ((void *) &sodata, (void *) data, sizeof (CamelSockOptData)); - if (PR_GetSocketOption (((CamelTcpStreamSSL *)stream)->sockfd, &sodata) == PR_FAILURE) + if (PR_GetSocketOption (((CamelTcpStreamSSL *)stream)->priv->sockfd, &sodata) == PR_FAILURE) return -1; memcpy ((void *) data, (void *) &sodata, sizeof (CamelSockOptData)); @@ -415,10 +438,16 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data) memset ((void *) &sodata, 0, sizeof (sodata)); memcpy ((void *) &sodata, (void *) data, sizeof (CamelSockOptData)); - if (PR_SetSocketOption (((CamelTcpStreamSSL *)stream)->sockfd, &sodata) == PR_FAILURE) + if (PR_SetSocketOption (((CamelTcpStreamSSL *)stream)->priv->sockfd, &sodata) == PR_FAILURE) return -1; return 0; } +static gpointer +stream_get_socket (CamelTcpStream *stream) +{ + return (gpointer) CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd; +} + #endif /* HAVE_NSS */ diff --git a/camel/camel-tcp-stream-ssl.h b/camel/camel-tcp-stream-ssl.h index 883e1cda2a..af68fe9644 100644 --- a/camel/camel-tcp-stream-ssl.h +++ b/camel/camel-tcp-stream-ssl.h @@ -30,12 +30,8 @@ extern "C" { #pragma } #endif /* __cplusplus */ -#include <config.h> - -#ifdef HAVE_NSS #include <camel/camel-tcp-stream.h> #include <camel/camel-service.h> -#include <nspr.h> #define CAMEL_TCP_STREAM_SSL_TYPE (camel_tcp_stream_ssl_get_type ()) #define CAMEL_TCP_STREAM_SSL(obj) (CAMEL_CHECK_CAST((obj), CAMEL_TCP_STREAM_SSL_TYPE, CamelTcpStreamSSL)) @@ -45,10 +41,7 @@ extern "C" { struct _CamelTcpStreamSSL { CamelTcpStream parent_object; - PRFileDesc *sockfd; - - CamelService *service; - char *expected_host; + struct _CamelTcpStreamSSLPrivate *priv; }; typedef struct { @@ -64,7 +57,6 @@ CamelType camel_tcp_stream_ssl_get_type (void); /* public methods */ CamelStream *camel_tcp_stream_ssl_new (CamelService *service, const char *expected_host); -#endif /* HAVE_NSS */ #ifdef __cplusplus } diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c index f42fa0f1d5..acbd108212 100644 --- a/camel/camel-tcp-stream.c +++ b/camel/camel-tcp-stream.c @@ -33,6 +33,7 @@ static CamelStreamClass *parent_class = NULL; static int tcp_connect (CamelTcpStream *stream, struct hostent *host, int port); static int tcp_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); static int tcp_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data); +static gpointer tcp_get_socket (CamelTcpStream *stream); static void camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class) @@ -46,6 +47,7 @@ camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class) camel_tcp_stream_class->connect = tcp_connect; camel_tcp_stream_class->getsockopt = tcp_getsockopt; camel_tcp_stream_class->setsockopt = tcp_setsockopt; + camel_tcp_stream_class->get_socket = tcp_get_socket; } static void @@ -150,3 +152,28 @@ camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *dat return CTS_CLASS (stream)->setsockopt (stream, data); } + + +static gpointer +tcp_get_socket (CamelTcpStream *stream) +{ + g_warning ("CamelTcpStream::get_socket called on default implementation\n"); + return NULL; +} + + +/** + * camel_tcp_stream_get_socket: + * @stream: tcp stream object + * + * Get the stream's socket. + * + * Return value: the stream's socket on success or NULL on failure. + **/ +gpointer +camel_tcp_stream_get_socket (CamelTcpStream *stream) +{ + g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL); + + return CTS_CLASS (stream)->get_socket (stream); +} diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h index 79d3f90f08..68153d3734 100644 --- a/camel/camel-tcp-stream.h +++ b/camel/camel-tcp-stream.h @@ -100,7 +100,8 @@ typedef struct { int (*connect) (CamelTcpStream *stream, struct hostent *host, int port); int (*getsockopt) (CamelTcpStream *stream, CamelSockOptData *data); int (*setsockopt) (CamelTcpStream *stream, const CamelSockOptData *data); - + + gpointer (*get_socket) (CamelTcpStream *stream); } CamelTcpStreamClass; /* Standard Camel function */ @@ -111,6 +112,8 @@ int camel_tcp_stream_connect (CamelTcpStream *stream, struct hostent int camel_tcp_stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data); int camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data); +gpointer camel_tcp_stream_get_socket (CamelTcpStream *stream); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c index 93d0447c2f..9d60891f04 100644 --- a/camel/providers/smtp/camel-smtp-transport.c +++ b/camel/providers/smtp/camel-smtp-transport.c @@ -253,17 +253,19 @@ smtp_connect (CamelService *service, CamelException *ex) addrlen = sizeof (transport->localaddr); #ifdef HAVE_NSS if (use_ssl) { + PRFileDesc *sockfd = camel_tcp_stream_get_socket (CAMEL_TCP_STREAM (tcp_stream)); PRNetAddr addr; char hname[1024]; - PR_GetSockName (CAMEL_TCP_STREAM_SSL (tcp_stream)->sockfd, &addr); + PR_GetSockName (sockfd, &addr); memset (hname, 0, sizeof (hname)); PR_NetAddrToString (&addr, hname, 1023); inet_aton (hname, (struct in_addr *)&transport->localaddr.sin_addr); } else { - getsockname (CAMEL_TCP_STREAM_RAW (tcp_stream)->sockfd, - (struct sockaddr *)&transport->localaddr, &addrlen); + int sockfd = GPOINTER_TO_INT (camel_tcp_stream_get_socket (CAMEL_TCP_STREAM (tcp_stream))); + + getsockname (sockfd, (struct sockaddr *)&transport->localaddr, &addrlen); } #else getsockname (CAMEL_TCP_STREAM_RAW (tcp_stream)->sockfd, |