source: trunk/third/gnome-vfs/libgnomevfs/gnome-vfs-ssl.c @ 17128

Revision 17128, 5.4 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17127, which included commits to RCS files with non-trunk default branches.
RevLine 
[17127]1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3/* gnome-vfs-ssl.h
4 *
5 * Copyright (C) 2001 Ian McKellar
6 *
7 * The Gnome Library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * The Gnome Library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with the Gnome Library; see the file COPYING.LIB.  If not,
19 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22/*
23 * Authors: Ian McKellar <yakk@yakk.net>
24 *   My knowledge of SSL programming is due to reading Jeffrey Stedfast's
25 *   excellent SSL implementation in Evolution.
26 */
27
28#include <config.h>
29#include "gnome-vfs-ssl.h"
30
31#include <string.h>
32#include <glib.h>
33#include "gnome-vfs.h"
34#include "gnome-vfs-private.h"
35#include "gnome-vfs-ssl-private.h"
36
37#ifdef HAVE_OPENSSL
38#include <openssl/ssl.h>
39#include <openssl/x509.h>
40#include <openssl/err.h>
41#include <sys/time.h>
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <unistd.h>
45#include <fcntl.h>
46#include <errno.h>
47#include <netinet/in.h>
48#include <netdb.h>
49#include <sys/socket.h>
50#endif
51
52typedef struct {
53#ifdef HAVE_OPENSSL
54        int sockfd;
55        SSL *ssl;
56#else
57#ifdef HAVE_NSS
58        PRFileDesc *sockfd;
59#else
60        char    dummy;
61#endif
62#endif
63} GnomeVFSSSLPrivate;
64
65struct GnomeVFSSSL {
66        GnomeVFSSSLPrivate *private;
67};
68
69void
70gnome_vfs_ssl_init () {
71#ifdef HAVE_OPENSSL
72        SSL_library_init ();
73#endif
74}
75
76gboolean
77gnome_vfs_ssl_enabled ()
78{
79#ifdef HAVE_OPENSSL
80        return TRUE;
81#else
82        return FALSE;
83#endif
84}
85
86/* FIXME: add *some* kind of cert verification! */
87GnomeVFSResult
88gnome_vfs_ssl_create (GnomeVFSSSL **handle_return,
89                      const char *host,
90                      unsigned int port)
91{
92#ifdef HAVE_OPENSSL
93        int fd;
94        int ret;
95        struct hostent *h;
96        struct sockaddr_in sin;
97
98        sin.sin_port = htons (port);
99        h = gethostbyname (host);
100
101        if (h == NULL) {
102                /* host lookup failed */
103                return gnome_vfs_result_from_h_errno ();
104        }
105
106        sin.sin_family = h->h_addrtype;
107        memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
108
109        fd = socket (h->h_addrtype, SOCK_STREAM, 0);
110        if (fd < 0) {
111                return gnome_vfs_result_from_errno ();
112        }
113
114        ret = connect (fd, (struct sockaddr *)&sin, sizeof (sin));
115        if (ret == -1) {
116                /* connect failed */
117                return gnome_vfs_result_from_errno ();
118        }
119
120        return gnome_vfs_ssl_create_from_fd (handle_return, fd);
121#else
122        return GNOME_VFS_ERROR_NOT_SUPPORTED;
123#endif
124}
125
126GnomeVFSResult
127gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return,
128                              gint fd)
129{
130#ifdef HAVE_OPENSSL
131        GnomeVFSSSL *ssl;
132        SSL_CTX *ssl_ctx = NULL;
133        int ret;
134
135        ssl = g_new0 (GnomeVFSSSL, 1);
136        ssl->private = g_new0 (GnomeVFSSSLPrivate, 1);
137        ssl->private->sockfd = fd;
138
139        /* SSLv23_client_method will negotiate with SSL v2, v3, or TLS v1 */
140        ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
141
142        if (ssl_ctx == NULL) {
143                return GNOME_VFS_ERROR_INTERNAL;
144        }
145
146        /* FIXME: SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, &ssl_verify);*/
147        ssl->private->ssl = SSL_new (ssl_ctx);
148
149        if (ssl->private->ssl == NULL) {
150                return GNOME_VFS_ERROR_IO;
151        }
152
153        SSL_set_fd (ssl->private->ssl, fd);
154
155        ret = SSL_connect (ssl->private->ssl);
156        if (ret != 1) {
157                SSL_shutdown (ssl->private->ssl);
158
159                if (ssl->private->ssl->ctx)
160                        SSL_CTX_free (ssl->private->ssl->ctx);
161
162                SSL_free (ssl->private->ssl);
163                g_free (ssl->private);
164                g_free (ssl);
165                return GNOME_VFS_ERROR_IO;
166        }
167
168        *handle_return = ssl;
169
170        return GNOME_VFS_OK;
171
172
173#else
174        return GNOME_VFS_ERROR_NOT_SUPPORTED;
175#endif
176}
177
178GnomeVFSResult
179gnome_vfs_ssl_read (GnomeVFSSSL *ssl,
180                    gpointer buffer,
181                    GnomeVFSFileSize bytes,
182                    GnomeVFSFileSize *bytes_read)
183{
184#if HAVE_OPENSSL
185        if (bytes == 0) {
186                *bytes_read = 0;
187                return GNOME_VFS_OK;
188        }
189
190        *bytes_read = SSL_read (ssl->private->ssl, buffer, bytes);
191
192        if (*bytes_read <= 0) {
193                *bytes_read = 0;
194                return GNOME_VFS_ERROR_GENERIC;
195        }
196        return GNOME_VFS_OK;
197#else
198        return GNOME_VFS_ERROR_NOT_SUPPORTED;
199#endif
200}
201
202GnomeVFSResult
203gnome_vfs_ssl_write (GnomeVFSSSL *ssl,
204                     gconstpointer buffer,
205                     GnomeVFSFileSize bytes,
206                     GnomeVFSFileSize *bytes_written)
207{
208#if HAVE_OPENSSL
209        if (bytes == 0) {
210                *bytes_written = 0;
211                return GNOME_VFS_OK;
212        }
213
214        *bytes_written = SSL_write (ssl->private->ssl, buffer, bytes);
215
216        if (*bytes_written <= 0) {
217                *bytes_written = 0;
218                return GNOME_VFS_ERROR_GENERIC;
219        }
220        return GNOME_VFS_OK;
221#else
222        return GNOME_VFS_ERROR_NOT_SUPPORTED;
223#endif
224}
225
226void
227gnome_vfs_ssl_destroy (GnomeVFSSSL *ssl)
228{
229#if HAVE_OPENSSL
230        SSL_shutdown (ssl->private->ssl);
231        SSL_CTX_free (ssl->private->ssl->ctx);
232        SSL_free (ssl->private->ssl);
233        close (ssl->private->sockfd);
234#else
235#endif
236        g_free (ssl->private);
237        g_free (ssl);
238}
239
240static GnomeVFSSocketImpl ssl_socket_impl = {
241        (GnomeVFSSocketReadFunc)gnome_vfs_ssl_read,
242        (GnomeVFSSocketWriteFunc)gnome_vfs_ssl_write,
243        (GnomeVFSSocketCloseFunc)gnome_vfs_ssl_destroy
244};
245
246GnomeVFSSocket *
247gnome_vfs_ssl_to_socket (GnomeVFSSSL *ssl)
248{
249        return gnome_vfs_socket_new (&ssl_socket_impl, ssl);
250}
Note: See TracBrowser for help on using the repository browser.