]> err.no Git - sope/blob - sope-core/NGStreams/NGActiveSSLSocket.m
Drop apache 1 build-dependency
[sope] / sope-core / NGStreams / NGActiveSSLSocket.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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
22 #include <NGStreams/NGActiveSSLSocket.h>
23 #include "common.h"
24
25 #if HAVE_OPENSSL
26 #  define id openssl_id
27 #  include <openssl/ssl.h>
28 #  undef id
29 #endif
30
31 @interface NGActiveSocket(UsedPrivates)
32 - (BOOL)primaryConnectToAddress:(id<NGSocketAddress>)_address;
33 @end
34
35 @implementation NGActiveSSLSocket
36
37 #if HAVE_OPENSSL
38
39 #if STREAM_BIO
40 static int streamBIO_bwrite(BIO *, const char *, int) {
41 }
42 static int streamBIO_bread(BIO *, char *, int) {
43 }
44 static int streamBIO_bputs(BIO *, const char *) {
45 }
46 static int streamBIO_bgets(BIO *, char *, int) {
47 }
48 static long streamBIO_ctrl(BIO *, int, long, void *) {
49 }
50 static int streamBIO_create(BIO *) {
51 }
52 static int streamBIO_destroy(BIO *) {
53 }
54 static long streamBIO_callback_ctrl(BIO *, int, bio_info_cb *) {
55 }
56
57 static BIO_METHOD streamBIO = {
58   0 /* type */,
59   "NGActiveSocket" /* name */,
60   streamBIO_bwrite,
61   streamBIO_bread,
62   streamBIO_bputs,
63   streamBIO_bgets,
64   streamBIO_ctrl,
65   streamBIO_create,
66   streamBIO_destroy,
67   streamBIO_callback_ctrl
68 };
69
70 // create: BIO_new(&streamBIO);
71
72 #endif /* STREAM_BIO */
73
74 - (id)initWithDomain:(id<NGSocketDomain>)_domain {
75   if ((self = [super initWithDomain:_domain])) {
76     //BIO *bio_err;
77     static BOOL didGlobalInit = NO;
78     
79     if (!didGlobalInit) {
80       /* Global system initialization*/
81       SSL_library_init();
82       SSL_load_error_strings();
83       didGlobalInit = YES;
84     }
85
86     /* An error write context */
87     //bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
88     
89     /* Create our context*/
90     
91     if ((self->ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
92       NSLog(@"ERROR(%s): couldn't create SSL context for v23 method !",
93             __PRETTY_FUNCTION__);
94       [self release];
95       return nil;
96     }
97   }
98   return self;
99 }
100
101 - (void)dealloc {
102   if (self->ctx) {
103     SSL_CTX_free(self->ctx);
104     self->ctx = NULL;
105   }
106   [super dealloc];
107 }
108
109 /* basic IO, reading and writing bytes */
110
111 - (unsigned)readBytes:(void *)_buf count:(unsigned)_len {
112   if (self->ssl == NULL)
113     // should throw error
114     return NGStreamError;
115   
116   return SSL_read(self->ssl, _buf, _len);
117 }
118 - (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len {
119   return SSL_write(self->ssl, _buf, _len);
120 }
121
122 /* connection and shutdown */
123
124 - (BOOL)markNonblockingAfterConnect {
125   return NO;
126 }
127 - (BOOL)primaryConnectToAddress:(id<NGSocketAddress>)_address {
128   if (self->ctx == NULL) {
129     NSLog(@"ERROR(%s): ctx isn't setup yet !",
130           __PRETTY_FUNCTION__);
131     return NO;
132   }
133
134   if ((self->ssl = SSL_new(self->ctx)) == NULL) {
135     // should set exception !
136     NSLog(@"ERROR(%s): couldn't create SSL socket structure ...",
137           __PRETTY_FUNCTION__);
138     return NO;
139   }
140   
141   if (![super primaryConnectToAddress:_address])
142     /* could not connect to Unix socket ... */
143     return NO;
144   
145   /* probably we should create a BIO for streams !!! */
146   if ((self->sbio = BIO_new_socket(self->fd, BIO_NOCLOSE)) == NULL) {
147     NSLog(@"ERROR(%s): couldn't create SSL socket IO structure ...",
148           __PRETTY_FUNCTION__);
149     [self shutdown];
150     return NO;
151   }
152   
153   NSAssert(self->ctx,  @"missing SSL context ...");
154   NSAssert(self->ssl,  @"missing SSL socket ...");
155   NSAssert(self->sbio, @"missing SSL BIO ...");
156   
157   SSL_set_bio(self->ssl, self->sbio, self->sbio);
158   if (SSL_connect(self->ssl) <= 0) {
159     NSLog(@"ERROR(%s): couldn't setup SSL connection on socket ...",
160           __PRETTY_FUNCTION__);
161     [self shutdown];
162     return NO;
163   }
164   
165   return YES;
166 }
167 - (BOOL)shutdown {
168   if (self->ctx) {
169     SSL_CTX_free(self->ctx);
170     self->ctx = NULL;
171   }
172   return [super shutdown];
173 }
174
175 #else /* no OpenSSL available */
176
177 + (void)initialize {
178   NSLog(@"WARNING: The NGActiveSSLSocket class was accessed, "
179         @"but OpenSSL support is turned off.");
180 }
181 - (id)initWithDomain:(id<NGSocketDomain>)_domain {
182   [self release];
183   return nil;
184 }
185
186 #endif
187
188 @end /* NGActiveSSLSocket */