source: protocols/ssl_openssl.c @ afe0764

Last change on this file since afe0764 was 701acdd4, checked in by Wilmer van der Gaast <wilmer@…>, at 2005-12-16T17:58:00Z

Non-blocking SSL handshakes for GnuTLS. The rest might come later, but is
slightly less important.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* SSL module - GnuTLS version                                          */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#include <openssl/crypto.h>
27#include <openssl/rand.h>
28#include <openssl/x509.h>
29#include <openssl/pem.h>
30#include <openssl/ssl.h>
31#include <openssl/err.h>
32
33#include "proxy.h"
34#include "ssl_client.h"
35#include "sock.h"
36
37int ssl_errno = 0;
38
39static gboolean initialized = FALSE;
40
41struct scd
42{
43        SslInputFunction func;
44        gpointer data;
45        int fd;
46        gboolean established;
47       
48        SSL *ssl;
49        SSL_CTX *ssl_ctx;
50};
51
52static void ssl_connected( gpointer data, gint source, GaimInputCondition cond );
53
54
55
56void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data )
57{
58        struct scd *conn = g_new0( struct scd, 1 );
59        SSL_METHOD *meth;
60       
61        conn->fd = proxy_connect( host, port, ssl_connected, conn );
62        conn->func = func;
63        conn->data = data;
64       
65        if( conn->fd < 0 )
66        {
67                g_free( conn );
68                return( NULL );
69        }
70       
71        if( !initialized )
72        {
73                initialized = TRUE;
74                SSLeay_add_ssl_algorithms();
75        }
76       
77        meth = TLSv1_client_method();
78        conn->ssl_ctx = SSL_CTX_new( meth );
79        if( conn->ssl_ctx == NULL )
80        {
81                conn->fd = -1;
82                return( NULL );
83        }
84       
85        conn->ssl = SSL_new( conn->ssl_ctx );
86        if( conn->ssl == NULL )
87        {
88                conn->fd = -1;
89                return( NULL );
90        }
91       
92        return( conn );
93}
94
95static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )
96{
97        struct scd *conn = data;
98       
99        if( source == -1 )
100                goto ssl_connected_failure;
101       
102        SSL_set_fd( conn->ssl, conn->fd );
103       
104        if( SSL_connect( conn->ssl ) < 0 )
105                goto ssl_connected_failure;
106       
107        conn->established = TRUE;
108        conn->func( conn->data, conn, cond );
109        return;
110       
111ssl_connected_failure:
112        conn->func( conn->data, NULL, cond );
113       
114        if( conn->ssl )
115        {
116                SSL_shutdown( conn->ssl );
117                SSL_free( conn->ssl );
118        }
119        if( conn->ssl_ctx )
120        {
121                SSL_CTX_free( conn->ssl_ctx );
122        }
123        if( source >= 0 ) closesocket( source );
124        g_free( conn );
125}
126
127int ssl_read( void *conn, char *buf, int len )
128{
129        if( !((struct scd*)conn)->established )
130                return( 0 );
131       
132        return( SSL_read( ((struct scd*)conn)->ssl, buf, len ) );
133}
134
135int ssl_write( void *conn, const char *buf, int len )
136{
137        if( !((struct scd*)conn)->established )
138                return( 0 );
139       
140        return( SSL_write( ((struct scd*)conn)->ssl, buf, len ) );
141}
142
143void ssl_disconnect( void *conn_ )
144{
145        struct scd *conn = conn_;
146       
147        if( conn->established )
148                SSL_shutdown( conn->ssl );
149       
150        closesocket( conn->fd );
151       
152        SSL_free( conn->ssl );
153        SSL_CTX_free( conn->ssl_ctx );
154        g_free( conn );
155}
156
157int ssl_getfd( void *conn )
158{
159        return( ((struct scd*)conn)->fd );
160}
Note: See TracBrowser for help on using the repository browser.