/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Authors: Jeffrey Stedfast <fejj@ximian.com> * * Copyright 2001 Ximian, Inc. (www.ximian.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * */ #include <config.h> #include "camel-stream-ssl.h" #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> static CamelStreamClass *parent_class = NULL; /* Returns the class for a CamelStreamSSL */ #define CSSSL_CLASS(so) CAMEL_STREAM_SSL_CLASS (CAMEL_OBJECT_GET_CLASS (so)) static SSL *open_ssl_connection (int sockfd); static int close_ssl_connection (SSL *ssl); static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n); static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n); static int stream_flush (CamelStream *stream); static int stream_close (CamelStream *stream); static void camel_stream_ssl_class_init (CamelStreamSSLClass *camel_stream_ssl_class) { CamelStreamClass *camel_stream_class = CAMEL_STREAM_CLASS (camel_stream_ssl_class); parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (camel_stream_get_type ())); /* virtual method overload */ camel_stream_class->read = stream_read; camel_stream_class->write = stream_write; camel_stream_class->flush = stream_flush; camel_stream_class->close = stream_close; } static void camel_stream_ssl_init (gpointer object, gpointer klass) { CamelStreamSSL *stream = CAMEL_STREAM_SSL (object); stream->fd = -1; stream->ssl = NULL; } static void camel_stream_ssl_finalize (CamelObject *object) { CamelStreamSSL *stream = CAMEL_STREAM_SSL (object); if (stream->ssl) { SSL_shutdown (stream->ssl); if (stream->ssl->ctx) SSL_CTX_free (stream->ssl->ctx); SSL_free (stream->ssl); } if (stream->fd != -1) close (stream->fd); } CamelType camel_stream_ssl_get_type (void) { static CamelType type = CAMEL_INVALID_TYPE; if (type == CAMEL_INVALID_TYPE) { type = camel_type_register (camel_stream_get_type (), "CamelStreamSSL", sizeof (CamelStreamSSL), sizeof (CamelStreamSSLClass), (CamelObjectClassInitFunc) camel_stream_ssl_class_init, NULL, (CamelObjectInitFunc) camel_stream_ssl_init, (CamelObjectFinalizeFunc) camel_stream_ssl_finalize); } return type; } static int verify_callback (int ok, X509_STORE_CTX *ctx) { char *str, buf[256]; X509 *cert; int err; 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, "CamelStreamSSL: depth=%d %s\n", ctx->error_depth, buf)); else d(fprintf (stderr, "CamelStreamSSL: 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: ok = 1; } } return ok; } static SSL * open_ssl_connection (int sockfd) { SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; int n; /* SSLv23_client_method will negotiate with SSL v2, v3, or TLS v1 */ ssl_ctx = SSL_CTX_new (SSLv23_client_method ()); SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, &verify_cb); ssl = SSL_new (ssl_ctx); SSL_set_fd (ssl, sockfd); n = SSL_connect (ssl); if (n != 1) { SSL_shutdown (ssl); if (ssl->ctx) SSL_CTX_free (ssl->ctx); SSL_free (ssl); ssl = NULL; } return ssl; } static int close_ssl_connection (SSL *ssl) { if (ssl) { SSL_shutdown (ssl); if (ssl->ctx) SSL_CTX_free (ssl->ctx); SSL_free (ssl); } return 0; } /** * camel_stream_ssl_new: * @sockfd: a socket file descriptor * * Returns a stream associated with the given file descriptor. * When the stream is destroyed, the file descriptor will be closed. * * Return value: the stream **/ CamelStream * camel_stream_ssl_new (int sockfd) { CamelStreamSSL *stream_ssl; SSL *ssl; if (sockfd == -1) return NULL; ssl = open_ssl_connection (sockfd); if (!ssl) return NULL; stream_ssl = CAMEL_STREAM_SSL (camel_object_new (camel_stream_ssl_get_type ())); stream_ssl->sockfd = sockfd; stream_ssl->ssl = ssl; return CAMEL_STREAM (stream_ssl); } static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n) { CamelStreamSSL *stream_ssl = CAMEL_STREAM_SSL (stream); ssize_t nread; do { nread = SSL_read (stream_ssl->ssl, buffer, n); } while (nread == -1 && errno == EINTR); return nread; } static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n) { CamelStreamSSL *stream_ssl = CAMEL_STREAM_SSL (stream); ssize_t v, written = 0; do { v = SSL_write (stream_ssl->ssl, buffer, n); if (v > 0) written += v; } while (v == -1 && errno == EINTR); if (v == -1) return -1; else return written; } static int stream_flush (CamelStream *stream) { return fsync (((CamelStreamSSL *)stream)->fd); } static int stream_close (CamelStream *stream) { close_ssl_connection (((CamelStreamSSL *)stream)->ssl); return close (((CamelStreamSSL *)stream)->fd); } orm'><form class='right' method='get' action='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/x11-servers/xorg-fontserver/pkg-plist'> <input type='hidden' name='h' value='gnome-3.24'/><select name='qt'> <option value='grep'>log msg</option> <option value='author'>author</option> <option value='committer'>committer</option> <option value='range'>range</option> </select> <input class='txt' type='search' size='10' name='q' value=''/> <input type='submit' value='search'/> </form> </td></tr></table> <div class='path'>path: <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/?h=gnome-3.24'>root</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/x11-servers?h=gnome-3.24'>x11-servers</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/x11-servers/xorg-fontserver?h=gnome-3.24'>xorg-fontserver</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24'>pkg-plist</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th></th><th class='left'>Commit message (<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Age</th><th class='left'>Files</th><th class='left'>Lines</th></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&id=a168db5e3f2a8601d058a656c6fd0de0509d7f88'>xorg-fontserver moved from x11-servers to x11-fonts (xfs).</a></td><td>flz</td><td><span title='2007-05-20 11:21:03 +0800'>2007-05-20</span></td><td>1</td><td><span class='deletions'>-5</span>/<span class='insertions'>+0</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&id=e31bed690b2fba4714686b691a351a51b98d80e8'>Replace ugly "@unexec rmdir %D... 2>/dev/null || true" with @dirrmtry</a></td><td>edwin</td><td><span title='2006-01-22 11:01:03 +0800'>2006-01-22</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&id=c39de4d86f08e509ed3f71318fbdea0e86bd8953'>Upgrade X.Org ports to 6.8.2.</a></td><td>lesi</td><td><span title='2005-03-18 07:22:13 +0800'>2005-03-18</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&id=5ed7787ddc20c519e5827ec787f9dedbf4c96dac'>Add rcNG startup script. [1]</a></td><td>lesi</td><td><span title='2005-01-24 03:50:40 +0800'>2005-01-24</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/x11-servers/xorg-fontserver/pkg-plist?h=gnome-3.24&id=65440fcd9bcb20a1d534ae744432598de80568e0'>Update X.Org ports to 6.8.1, and the DRI port to use Mesa 6.2. Because Mesa 6.2</a></td><td>anholt</td><td><span title='2004-12-23 09:35:49 +0800'>2004-12-23</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr>