]> err.no Git - sope/blob - sope-core/NGStreams/NGActiveSSLSocket.m
more code directory reorganizations
[sope] / sope-core / NGStreams / NGActiveSSLSocket.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include <NGStreams/NGActiveSSLSocket.h>
24 #include "common.h"
25
26 #if HAVE_OPENSSL
27 #  define id openssl_id
28 #  include <openssl/ssl.h>
29 #  undef id
30 #endif
31
32 @interface NGActiveSocket(UsedPrivates)
33 - (BOOL)primaryConnectToAddress:(id<NGSocketAddress>)_address;
34 @end
35
36 @implementation NGActiveSSLSocket
37
38 #if HAVE_OPENSSL
39
40 #if STREAM_BIO
41 static int streamBIO_bwrite(BIO *, const char *, int) {
42 }
43 static int streamBIO_bread(BIO *, char *, int) {
44 }
45 static int streamBIO_bputs(BIO *, const char *) {
46 }
47 static int streamBIO_bgets(BIO *, char *, int) {
48 }
49 static long streamBIO_ctrl(BIO *, int, long, void *) {
50 }
51 static int streamBIO_create(BIO *) {
52 }
53 static int streamBIO_destroy(BIO *) {
54 }
55 static long streamBIO_callback_ctrl(BIO *, int, bio_info_cb *) {
56 }
57
58 static BIO_METHOD streamBIO = {
59   0 /* type */,
60   "NGActiveSocket" /* name */,
61   streamBIO_bwrite,
62   streamBIO_bread,
63   streamBIO_bputs,
64   streamBIO_bgets,
65   streamBIO_ctrl,
66   streamBIO_create,
67   streamBIO_destroy,
68   streamBIO_callback_ctrl
69 };
70
71 // create: BIO_new(&streamBIO);
72
73 #endif /* STREAM_BIO */
74
75 - (id)initWithDomain:(id<NGSocketDomain>)_domain {
76   if ((self = [super initWithDomain:_domain])) {
77     //BIO *bio_err;
78     static BOOL didGlobalInit = NO;
79     
80     if (!didGlobalInit) {
81       /* Global system initialization*/
82       SSL_library_init();
83       SSL_load_error_strings();
84       didGlobalInit = YES;
85     }
86
87     /* An error write context */
88     //bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
89     
90     /* Create our context*/
91     
92     if ((self->ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
93       NSLog(@"ERROR(%s): couldn't create SSL context for v23 method !",
94             __PRETTY_FUNCTION__);
95       [self release];
96       return nil;
97     }
98   }
99   return self;
100 }
101
102 - (void)dealloc {
103   if (self->ctx) {
104     SSL_CTX_free(self->ctx);
105     self->ctx = NULL;
106   }
107   [super dealloc];
108 }
109
110 /* basic IO, reading and writing bytes */
111
112 - (unsigned)readBytes:(void *)_buf count:(unsigned)_len {
113   if (self->ssl == NULL)
114     // should throw error
115     return NGStreamError;
116   
117   return SSL_read(self->ssl, _buf, _len);
118 }
119 - (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len {
120   return SSL_write(self->ssl, _buf, _len);
121 }
122
123 /* connection and shutdown */
124
125 - (BOOL)markNonblockingAfterConnect {
126   return NO;
127 }
128 - (BOOL)primaryConnectToAddress:(id<NGSocketAddress>)_address {
129   if (self->ctx == NULL) {
130     NSLog(@"ERROR(%s): ctx isn't setup yet !",
131           __PRETTY_FUNCTION__);
132     return NO;
133   }
134
135   if ((self->ssl = SSL_new(self->ctx)) == NULL) {
136     // should set exception !
137     NSLog(@"ERROR(%s): couldn't create SSL socket structure ...",
138           __PRETTY_FUNCTION__);
139     return NO;
140   }
141   
142   if (![super primaryConnectToAddress:_address])
143     /* could not connect to Unix socket ... */
144     return NO;
145   
146   /* probably we should create a BIO for streams !!! */
147   if ((self->sbio = BIO_new_socket(self->fd, BIO_NOCLOSE)) == NULL) {
148     NSLog(@"ERROR(%s): couldn't create SSL socket IO structure ...",
149           __PRETTY_FUNCTION__);
150     [self shutdown];
151     return NO;
152   }
153   
154   NSAssert(self->ctx,  @"missing SSL context ...");
155   NSAssert(self->ssl,  @"missing SSL socket ...");
156   NSAssert(self->sbio, @"missing SSL BIO ...");
157   
158   SSL_set_bio(self->ssl, self->sbio, self->sbio);
159   if (SSL_connect(self->ssl) <= 0) {
160     NSLog(@"ERROR(%s): couldn't setup SSL connection on socket ...",
161           __PRETTY_FUNCTION__);
162     [self shutdown];
163     return NO;
164   }
165   
166   return YES;
167 }
168 - (BOOL)shutdown {
169   if (self->ctx) {
170     SSL_CTX_free(self->ctx);
171     self->ctx = NULL;
172   }
173   return [super shutdown];
174 }
175
176 #else /* no OpenSSL available */
177
178 + (void)initialize {
179   NSLog(@"WARNING: The NGActiveSSLSocket class was accessed, "
180         @"but OpenSSL support is turned off.");
181 }
182 - (id)initWithDomain:(id<NGSocketDomain>)_domain {
183   [self release];
184   return nil;
185 }
186
187 #endif
188
189 @end /* NGActiveSSLSocket */