/* Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOPE. SOPE is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SOPE 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "common.h" #if HAVE_OPENSSL # define id openssl_id # include # undef id #endif @interface NGActiveSocket(UsedPrivates) - (BOOL)primaryConnectToAddress:(id)_address; @end @implementation NGActiveSSLSocket #if HAVE_OPENSSL #if STREAM_BIO static int streamBIO_bwrite(BIO *, const char *, int) { } static int streamBIO_bread(BIO *, char *, int) { } static int streamBIO_bputs(BIO *, const char *) { } static int streamBIO_bgets(BIO *, char *, int) { } static long streamBIO_ctrl(BIO *, int, long, void *) { } static int streamBIO_create(BIO *) { } static int streamBIO_destroy(BIO *) { } static long streamBIO_callback_ctrl(BIO *, int, bio_info_cb *) { } static BIO_METHOD streamBIO = { 0 /* type */, "NGActiveSocket" /* name */, streamBIO_bwrite, streamBIO_bread, streamBIO_bputs, streamBIO_bgets, streamBIO_ctrl, streamBIO_create, streamBIO_destroy, streamBIO_callback_ctrl }; // create: BIO_new(&streamBIO); #endif /* STREAM_BIO */ - (id)initWithDomain:(id)_domain { if ((self = [super initWithDomain:_domain])) { //BIO *bio_err; static BOOL didGlobalInit = NO; if (!didGlobalInit) { /* Global system initialization*/ SSL_library_init(); SSL_load_error_strings(); didGlobalInit = YES; } /* An error write context */ //bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); /* Create our context*/ if ((self->ctx = SSL_CTX_new(SSLv23_method())) == NULL) { NSLog(@"ERROR(%s): couldn't create SSL context for v23 method !", __PRETTY_FUNCTION__); [self release]; return nil; } } return self; } - (void)dealloc { if (self->ctx) { SSL_CTX_free(self->ctx); self->ctx = NULL; } [super dealloc]; } /* basic IO, reading and writing bytes */ - (unsigned)readBytes:(void *)_buf count:(unsigned)_len { if (self->ssl == NULL) // should throw error return NGStreamError; return SSL_read(self->ssl, _buf, _len); } - (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len { return SSL_write(self->ssl, _buf, _len); } /* connection and shutdown */ - (BOOL)markNonblockingAfterConnect { return NO; } - (BOOL)primaryConnectToAddress:(id)_address { if (self->ctx == NULL) { NSLog(@"ERROR(%s): ctx isn't setup yet !", __PRETTY_FUNCTION__); return NO; } if ((self->ssl = SSL_new(self->ctx)) == NULL) { // should set exception ! NSLog(@"ERROR(%s): couldn't create SSL socket structure ...", __PRETTY_FUNCTION__); return NO; } if (![super primaryConnectToAddress:_address]) /* could not connect to Unix socket ... */ return NO; /* probably we should create a BIO for streams !!! */ if ((self->sbio = BIO_new_socket(self->fd, BIO_NOCLOSE)) == NULL) { NSLog(@"ERROR(%s): couldn't create SSL socket IO structure ...", __PRETTY_FUNCTION__); [self shutdown]; return NO; } NSAssert(self->ctx, @"missing SSL context ..."); NSAssert(self->ssl, @"missing SSL socket ..."); NSAssert(self->sbio, @"missing SSL BIO ..."); SSL_set_bio(self->ssl, self->sbio, self->sbio); if (SSL_connect(self->ssl) <= 0) { NSLog(@"ERROR(%s): couldn't setup SSL connection on socket ...", __PRETTY_FUNCTION__); [self shutdown]; return NO; } return YES; } - (BOOL)shutdown { if (self->ctx) { SSL_CTX_free(self->ctx); self->ctx = NULL; } return [super shutdown]; } #else /* no OpenSSL available */ + (void)initialize { NSLog(@"WARNING: The NGActiveSSLSocket class was accessed, " @"but OpenSSL support is turned off."); } - (id)initWithDomain:(id)_domain { [self release]; return nil; } #endif @end /* NGActiveSSLSocket */