Refactored SSL and callbacks
This commit is contained in:
parent
d87c7454b5
commit
3efc86a341
|
@ -18,7 +18,7 @@ struct aisl_config
|
||||||
uint32_t servers_spool_size;
|
uint32_t servers_spool_size;
|
||||||
uint32_t clients_spool_size;
|
uint32_t clients_spool_size;
|
||||||
uint32_t ssl_spool_size;
|
uint32_t ssl_spool_size;
|
||||||
uint32_t events_spool_size;
|
uint32_t callbacks_spool_size;
|
||||||
uint32_t initial_buffer_size;
|
uint32_t initial_buffer_size;
|
||||||
uint32_t clients_accept_limit;
|
uint32_t clients_accept_limit;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ aisl_server_t
|
||||||
aisl_listen( aisl_t instance, const char * address, uint16_t port );
|
aisl_listen( aisl_t instance, const char * address, uint16_t port );
|
||||||
|
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
|
|
||||||
aisl_status_t
|
aisl_status_t
|
||||||
aisl_set_ssl( aisl_t instance,
|
aisl_set_ssl( aisl_t instance,
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* callback.c
|
||||||
|
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* src/callback.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
|
||||||
|
*
|
||||||
|
* Project homepage: https://lowenware.com/aisl/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AISL_CALLBACK_H_43D3FC6B_22E5_481C_8EB2_00BF8C3D52CA
|
||||||
|
#define AISL_CALLBACK_H_43D3FC6B_22E5_481C_8EB2_00BF8C3D52CA
|
||||||
|
|
||||||
|
#include <aisl/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct callback
|
||||||
|
{
|
||||||
|
void * source;
|
||||||
|
aisl_callback_t callback;
|
||||||
|
aisl_event_t eevent;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct callback * callback_t;
|
||||||
|
|
||||||
|
|
||||||
|
static listener_t
|
||||||
|
listener_new( void * source, aisl_event_t e_id, aisl_callback_t cb)
|
||||||
|
{
|
||||||
|
listener_t self = malloc(sizeof(struct listener));
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
self->source = source;
|
||||||
|
self->e_id = e_id;
|
||||||
|
self->cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !AISL_CALLBACK_H */
|
231
src/instance.c
231
src/instance.c
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
#include "ssl.h"
|
||||||
//#include "globals.h"
|
//#include "globals.h"
|
||||||
//#include "stream.h"
|
//#include "stream.h"
|
||||||
#include "instance.h"
|
#include "instance.h"
|
||||||
|
@ -32,12 +33,22 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct callback
|
||||||
|
{
|
||||||
|
void * source;
|
||||||
|
aisl_callback_t callback;
|
||||||
|
aisl_event_t eevent;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct callback * callback_t;
|
||||||
|
|
||||||
|
|
||||||
struct aisl
|
struct aisl
|
||||||
{
|
{
|
||||||
list_t servers;
|
list_t servers;
|
||||||
list_t clients;
|
list_t clients;
|
||||||
list_t callbacks;
|
list_t callbacks;
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
list_t ssl;
|
list_t ssl;
|
||||||
#endif
|
#endif
|
||||||
buffer_t buffer;
|
buffer_t buffer;
|
||||||
|
@ -49,7 +60,7 @@ struct aisl
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
static uint32_t m_instances = 0;
|
static uint32_t m_instances = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -62,7 +73,7 @@ aisl_new( aisl_config_t config )
|
||||||
{
|
{
|
||||||
aisl_t instance;
|
aisl_t instance;
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
if ((m_instances++) == 0)
|
if ((m_instances++) == 0)
|
||||||
{
|
{
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
|
@ -85,7 +96,7 @@ aisl_new( aisl_config_t config )
|
||||||
if ( !(instance->buffer = buffer_new(config->initial_buffer_size)) )
|
if ( !(instance->buffer = buffer_new(config->initial_buffer_size)) )
|
||||||
goto release;
|
goto release;
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
if ( !(instance->ssl = list_new(config->ssl_spool_size)) )
|
if ( !(instance->ssl = list_new(config->ssl_spool_size)) )
|
||||||
goto release;
|
goto release;
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,15 +130,17 @@ aisl_free( aisl_t instance )
|
||||||
if (instance->buffer)
|
if (instance->buffer)
|
||||||
buffer_free(instance->buffer);
|
buffer_free(instance->buffer);
|
||||||
|
|
||||||
|
#ifndef AISL_WITHOUT_SSL
|
||||||
if (instance->ssl)
|
if (instance->ssl)
|
||||||
list_free(instance->ssl, (list_destructor_t) ssl_free );
|
list_free(instance->ssl, (list_destructor_t) ssl_free );
|
||||||
|
#endif
|
||||||
|
|
||||||
if (instance->last_error)
|
if (instance->last_error)
|
||||||
free(instance->last_error);
|
free(instance->last_error);
|
||||||
|
|
||||||
free(instance);
|
free(instance);
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
if ((--m_instances) == 0)
|
if ((--m_instances) == 0)
|
||||||
{
|
{
|
||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
|
@ -142,10 +155,8 @@ aisl_listen( aisl_t instance, const char * address, uint16_t port )
|
||||||
{
|
{
|
||||||
aisl_server_t result;
|
aisl_server_t result;
|
||||||
|
|
||||||
if ( (result = aisl_server_new(address, port)) != NULL )
|
if ( (result = aisl_server_new(instance, address, port)) != NULL )
|
||||||
{
|
{
|
||||||
result->instance = instance;
|
|
||||||
|
|
||||||
if (list_append(instance->servers, result) == LIST_NAN)
|
if (list_append(instance->servers, result) == LIST_NAN)
|
||||||
{
|
{
|
||||||
aisl_server_free(result);
|
aisl_server_free(result);
|
||||||
|
@ -156,128 +167,71 @@ aisl_listen( aisl_t instance, const char * address, uint16_t port )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef AISL_WITH_SSL
|
#ifndef AISL_WITHOUT_SSL
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_ssl_context( SSL * ssl, int * ptr, void * handle )
|
|
||||||
{
|
|
||||||
const char * server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
|
||||||
|
|
||||||
SSL_CTX * ctx = aisl_get_ssl_ctx( (aisl_t) handle, server_name );
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
{
|
|
||||||
SSL_set_SSL_CTX(ssl, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static SSL_CTX *
|
|
||||||
create_ssl_context( aisl_t instance,
|
|
||||||
const char * key_file,
|
|
||||||
const char * crt_file )
|
|
||||||
{
|
|
||||||
const SSL_METHOD * method;
|
|
||||||
SSL_CTX * ctx;
|
|
||||||
|
|
||||||
method = SSLv23_server_method();
|
|
||||||
|
|
||||||
if ( !(ctx = SSL_CTX_new(method)) )
|
|
||||||
goto except;
|
|
||||||
|
|
||||||
SSL_CTX_set_ecdh_auto(ctx, 1);
|
|
||||||
|
|
||||||
SSL_CTX_set_tlsext_servername_callback( ctx, get_ssl_context );
|
|
||||||
SSL_CTX_set_tlsext_servername_arg( ctx, (void *) instance );
|
|
||||||
|
|
||||||
if (!(SSL_CTX_use_certificate_file(ctx, crt_file, SSL_FILETYPE_PEM) > 0))
|
|
||||||
goto release;
|
|
||||||
|
|
||||||
if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) > 0))
|
|
||||||
goto release;
|
|
||||||
|
|
||||||
goto finally;
|
|
||||||
|
|
||||||
release:
|
|
||||||
SSL_CTX_free(ctx);
|
|
||||||
ctx = NULL;
|
|
||||||
|
|
||||||
except:
|
|
||||||
aisl_set_error( instance, ERR_error_string(ERR_get_error(),NULL) );
|
|
||||||
|
|
||||||
finally:
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((visibility ("default") ))
|
__attribute__ ((visibility ("default") ))
|
||||||
aisl_status_t
|
aisl_status_t
|
||||||
aisl_set_ssl( aisl_t instance, const char * server_name,
|
aisl_set_ssl( aisl_t instance, const char * domain,
|
||||||
const char * key_file,
|
const char * key_file,
|
||||||
const char * crt_file )
|
const char * crt_file )
|
||||||
{
|
{
|
||||||
SSL_CTX * ssl_ctx = NULL;
|
SSL_CTX * ssl_ctx = NULL;
|
||||||
int i;
|
ssl_t ssl;
|
||||||
crypter_t crypter;
|
size_t i;
|
||||||
|
|
||||||
/* lookup for existing contexts */
|
/* lookup for existing contexts */
|
||||||
for (i=0; i<instance->crypters->count; i++)
|
for (i=0; i<instance->ssl->count; i++)
|
||||||
{
|
{
|
||||||
crypter = list_index(instance->crypters, i);
|
ssl = list_index(instance->ssl, i);
|
||||||
if (crypter->keyFile && strcmp(crypter->keyFile, key_file)==0 &&
|
if (ssl->key_file && strcmp(ssl->key_file, key_file)==0 &&
|
||||||
crypter->crtFile && strcmp(crypter->crtFile, crt_file)==0 )
|
ssl->crt_file && strcmp(ssl->crt_file, crt_file)==0 )
|
||||||
{
|
{
|
||||||
ssl_ctx = crypter->sslCtx;
|
if ((ssl_ctx = crypter->ssl_ctx) != NULL)
|
||||||
key_file = NULL;
|
{
|
||||||
crt_file = NULL;
|
key_file = NULL;
|
||||||
break;
|
crt_file = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (crypter = crypter_new(server_name, key_file, crt_file)) )
|
if ((ssl = ssl_new(domain, key_file, crt_file)) != NULL)
|
||||||
{
|
{
|
||||||
return AISL_MALLOC_ERROR;
|
if (! ssl_ctx)
|
||||||
}
|
ssl_ctx = ssl__new_context(key_file, crt_file, (void*)instance);
|
||||||
|
|
||||||
if (! ssl_ctx)
|
if (ssl_ctx)
|
||||||
{
|
|
||||||
if (!(ssl_ctx = create_ssl_context(instance, key_file, crt_file)))
|
|
||||||
{
|
{
|
||||||
crypter_free(crypter);
|
ssl->ctx = ssl_ctx;
|
||||||
return AISL_EXTCALL_ERROR;
|
if (list_append(instance->ssl, ssl) != LIST_NAN)
|
||||||
|
{
|
||||||
|
return AISL_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssl_free(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypter->sslCtx = ssl_ctx;
|
return AISL_MALLOC_ERROR;
|
||||||
|
|
||||||
if (list_append(instance->crypters, crypter)==-1)
|
|
||||||
{
|
|
||||||
crypter_free(crypter);
|
|
||||||
return AISL_MALLOC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AISL_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SSL_CTX *
|
SSL_CTX *
|
||||||
aisl_get_ssl_ctx( aisl_t instance, const char * server_name )
|
aisl_get_ssl_ctx( aisl_t instance, const char * domain )
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
crypter_t crypter;
|
ssl_t ssl;
|
||||||
|
|
||||||
for (i=0; i<instance->crypters->count; i++)
|
if (domain)
|
||||||
{
|
{
|
||||||
crypter = list_index(instance->crypters, i);
|
for (i=0; i<instance->ssl->count; i++)
|
||||||
if (server_name)
|
|
||||||
{
|
{
|
||||||
if (strcmp(crypter->srvName, server_name)!=0)
|
ssl = list_index(instance->ssl, i);
|
||||||
|
if (strcmp(ssl->domain, domain) != 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
return crypter->sslCtx;
|
return ssl->ctx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -288,35 +242,39 @@ aisl_get_ssl_ctx( aisl_t instance, const char * server_name )
|
||||||
|
|
||||||
__attribute__ ((visibility ("default") ))
|
__attribute__ ((visibility ("default") ))
|
||||||
aisl_status_t
|
aisl_status_t
|
||||||
aisl_set_callback( aisl_t instance,
|
aisl_set_callback( aisl_t instance,
|
||||||
void * source,
|
void * source,
|
||||||
aisl_event_t e_id,
|
aisl_event_t event,
|
||||||
aisl_callback_t cb )
|
aisl_callback_t callback )
|
||||||
{
|
{
|
||||||
listener_t listener;
|
callback_t cb;
|
||||||
|
|
||||||
if (! (listener = listener_new(source, e_id, cb)) )
|
if ( (cb = malloc(sizeof(struct callback))) != NULL )
|
||||||
return AISL_MALLOC_ERROR;
|
|
||||||
|
|
||||||
if (list_append(instance->callbacks, listener) == -1)
|
|
||||||
{
|
{
|
||||||
free(listener);
|
cb->source = source;
|
||||||
return AISL_MALLOC_ERROR;
|
cb->event = event;
|
||||||
}
|
cb->callback = callback;
|
||||||
|
|
||||||
if (e_id == AISL_STREAM_OUTPUT) /* subscribtion for chunked output */
|
if ( list_append(instance->callbacks, cb) != LIST_NAN )
|
||||||
{
|
|
||||||
if (source)
|
|
||||||
{
|
{
|
||||||
( (stream_t) source )->flags |= STREAM_FLAG_OUTPUT_CHUNKED;
|
switch(event)
|
||||||
}
|
{
|
||||||
}
|
case AISL_STREAM_OUTPUT:
|
||||||
else if (e_id == AISL_STREAM_OPEN)
|
if (source)
|
||||||
{
|
stream_set_chunked_output( (aisl_stream_t) source );
|
||||||
instance->flags |= AISL_HANDLE_HAS_STREAM_LISTENERS;
|
//( (stream_t) source )->flags |= STREAM_FLAG_OUTPUT_CHUNKED;
|
||||||
}
|
break;
|
||||||
|
|
||||||
return AISL_SUCCESS;
|
case AISL_STREAM_OPEN:
|
||||||
|
instance->flags |= AISL_FLAG_HAS_STREAM_LISTENERS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AISL_SUCCESS;
|
||||||
|
}
|
||||||
|
free(cb);
|
||||||
|
}
|
||||||
|
return AISL_MALLOC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,20 +282,23 @@ __attribute__ ((visibility ("default") ))
|
||||||
void
|
void
|
||||||
aisl_unset_callback_for( aisl_t instance, void * source )
|
aisl_unset_callback_for( aisl_t instance, void * source )
|
||||||
{
|
{
|
||||||
int i=instance->callbacks->count-1;
|
size_t i = instance->callbacks->count;
|
||||||
while ( !(i < 0) )
|
|
||||||
{
|
|
||||||
listener_t listener = list_index(instance->callbacks, i);
|
|
||||||
if ( listener->source == source )
|
|
||||||
{
|
|
||||||
free(listener);
|
|
||||||
list_remove_index(instance->callbacks, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
i--;
|
if (i)
|
||||||
|
{
|
||||||
|
for(i=i-1; i <= 0; i-- )
|
||||||
|
{
|
||||||
|
callback_t callback = list_index(instance->callbacks, i);
|
||||||
|
if ( callback->source == source )
|
||||||
|
{
|
||||||
|
free(callback);
|
||||||
|
list_remove_index(instance->callbacks, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__attribute__ ((visibility ("default") ))
|
__attribute__ ((visibility ("default") ))
|
||||||
bool
|
bool
|
||||||
aisl_raise( aisl_t instance,
|
aisl_raise( aisl_t instance,
|
||||||
|
|
87
src/list.h
87
src/list.h
|
@ -1,120 +1,47 @@
|
||||||
/* list.h - header file of the list_t module
|
#ifndef AISL_LIST_H_3223EF5C_CCF2_4D7C_8A3B_8BAF122E473F
|
||||||
* Copyright (c) 2017 Löwenware Ltd (https://lowenware.com)
|
#define AISL_LIST_H_3223EF5C_CCF2_4D7C_8A3B_8BAF122E473F
|
||||||
*
|
|
||||||
* REPOSITORY:
|
|
||||||
* https://github.com/lowenware.com:cStuff.git
|
|
||||||
* MAINTAINER:
|
|
||||||
* Ilja Kartaschoff <ik@lowenware.com>
|
|
||||||
*
|
|
||||||
* LICENSE and DISCLAIMER:
|
|
||||||
* All code stored in this repository is designed to solve
|
|
||||||
* very common and widely meet development tasks. We are not about to patent
|
|
||||||
* wheels here, so all code you can find in this repository is FREE:
|
|
||||||
* you can use, redistribute and/or modify it without any limits or
|
|
||||||
* restrictions.
|
|
||||||
*
|
|
||||||
* All code described above is distributed in hope to be useful for somebody
|
|
||||||
* else WITHOUT ANY WARRANTY, without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* In case of questions or suggestions, feel free to contact maintainer.
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
#ifndef _CSTUFF_LIST_H_
|
|
||||||
#define _CSTUFF_LIST_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* MODULE: list_t
|
#define LIST_NAN (~0)
|
||||||
* Dynamic storage for pointers */
|
|
||||||
|
|
||||||
/* structure ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
struct list
|
struct list
|
||||||
{
|
{
|
||||||
void **list; /* list itself */
|
void ** list;
|
||||||
int size; /* number of bytes allocated for list */
|
size_t size;
|
||||||
int count; /* number of defined items in list */
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct list * list_t;
|
typedef struct list * list_t;
|
||||||
|
|
||||||
/* callback to free memory used by stored item ------------------------------ */
|
|
||||||
|
|
||||||
typedef void (* list_destructor_t)(void * list_item);
|
typedef void (* list_destructor_t)(void * list_item);
|
||||||
|
|
||||||
/* functions ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* get list item by index macro
|
|
||||||
* @self : list_t instance
|
|
||||||
* @index : item index
|
|
||||||
* @result : stored pointer
|
|
||||||
* */
|
|
||||||
#define list_index(self, index) (self->list[index])
|
#define list_index(self, index) (self->list[index])
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* create new list_t object
|
|
||||||
* @size : initial list size
|
|
||||||
* @result new list_t instance
|
|
||||||
* */
|
|
||||||
list_t
|
list_t
|
||||||
list_new(int size);
|
list_new(int size);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* free resources allocated for list_t instance
|
|
||||||
* @self : list_t instance
|
|
||||||
* @destructor : if set, destructor method will be called for each not-null
|
|
||||||
* list entry
|
|
||||||
* */
|
|
||||||
void
|
void
|
||||||
list_free(list_t self, list_destructor_t destructor);
|
list_free(list_t self, list_destructor_t destructor);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* insert new item into list at some position,
|
|
||||||
* memory will be allocated if necessary
|
|
||||||
* @self : list_t instance
|
|
||||||
* @item : pointer to be inserted
|
|
||||||
* @position : number from 0(prepend) to list size (append)
|
|
||||||
* */
|
|
||||||
int
|
int
|
||||||
list_insert( list_t self, void * item, int position );
|
list_insert( list_t self, void * item, int position );
|
||||||
|
|
||||||
/* append item to queue list
|
|
||||||
* @self : list_t object
|
|
||||||
* @item : pointer to be appended
|
|
||||||
* @result : position at which pointer was stored
|
|
||||||
* */
|
|
||||||
int
|
int
|
||||||
list_append(list_t self, void * item);
|
list_append(list_t self, void * item);
|
||||||
|
|
||||||
|
|
||||||
/* remove pointer from list
|
|
||||||
* @self : list_t object
|
|
||||||
* @item : to be removed
|
|
||||||
* */
|
|
||||||
void
|
void
|
||||||
list_remove( list_t self, void * item );
|
list_remove( list_t self, void * item );
|
||||||
|
|
||||||
|
|
||||||
/* remove pointer from list by index
|
|
||||||
* @self : list_t object
|
|
||||||
* @index : index of pointer to be removed
|
|
||||||
* */
|
|
||||||
void *
|
void *
|
||||||
list_remove_index( list_t self, int index );
|
list_remove_index( list_t self, int index );
|
||||||
|
|
||||||
|
|
||||||
/* set pointer by index. if element does not exist, list won't be extended
|
|
||||||
* @self : list_t object
|
|
||||||
* @index : index of pointer to be removed
|
|
||||||
* @value : value to be set
|
|
||||||
* */
|
|
||||||
void
|
void
|
||||||
list_set_item(list_t self, int index, void * value);
|
list_set_item(list_t self, int index, void * value);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif /* !AISL_LIST_H */
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <aisl/types.h>
|
#include <aisl/types.h>
|
||||||
#include <aisl/instance.h>
|
|
||||||
#include <aisl/server.h>
|
#include <aisl/server.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@
|
||||||
|
|
||||||
|
|
||||||
aisl_server_t
|
aisl_server_t
|
||||||
aisl_server_new(const char * address, int port);
|
aisl_server_new(aisl_t instance, const char * address, int port);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* ssl.c
|
||||||
|
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include "ssl.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AISL_WITHOUT_SSL
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_ssl_context( SSL * ssl, int * ptr, void * handle )
|
||||||
|
{
|
||||||
|
const char * server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
|
SSL_CTX * ctx = aisl_get_ssl_ctx( (aisl_t) handle, server_name );
|
||||||
|
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
SSL_set_SSL_CTX(ssl, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static SSL_CTX *
|
||||||
|
create_ssl_context( aisl_t instance,
|
||||||
|
const char * key_file,
|
||||||
|
const char * crt_file )
|
||||||
|
{
|
||||||
|
const SSL_METHOD * method;
|
||||||
|
SSL_CTX * ctx;
|
||||||
|
|
||||||
|
method = SSLv23_server_method();
|
||||||
|
|
||||||
|
if ( !(ctx = SSL_CTX_new(method)) )
|
||||||
|
goto except;
|
||||||
|
|
||||||
|
SSL_CTX_set_ecdh_auto(ctx, 1);
|
||||||
|
|
||||||
|
SSL_CTX_set_tlsext_servername_callback( ctx, get_ssl_context );
|
||||||
|
SSL_CTX_set_tlsext_servername_arg( ctx, (void *) instance );
|
||||||
|
|
||||||
|
if (!(SSL_CTX_use_certificate_file(ctx, crt_file, SSL_FILETYPE_PEM) > 0))
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) > 0))
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
goto finally;
|
||||||
|
|
||||||
|
release:
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
|
||||||
|
except:
|
||||||
|
aisl_set_error( instance, ERR_error_string(ERR_get_error(),NULL) );
|
||||||
|
|
||||||
|
finally:
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crypter_free( crypter_t self )
|
||||||
|
{
|
||||||
|
if (self->srvName)
|
||||||
|
free(self->srvName);
|
||||||
|
|
||||||
|
if (self->keyFile)
|
||||||
|
{
|
||||||
|
free(self->keyFile);
|
||||||
|
SSL_CTX_free(self->sslCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->crtFile)
|
||||||
|
free(self->crtFile);
|
||||||
|
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static crypter_t
|
||||||
|
crypter_new( const char * server_name,
|
||||||
|
const char * key_file,
|
||||||
|
const char * crt_file )
|
||||||
|
{
|
||||||
|
crypter_t self;
|
||||||
|
|
||||||
|
if ( (self=calloc(1, sizeof(struct crypter))) != NULL )
|
||||||
|
{
|
||||||
|
if (!(self->srvName = str_copy( server_name ? server_name : "*" )))
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
if ( key_file && !(self->keyFile = str_copy(key_file)))
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
if ( crt_file && !(self->crtFile = str_copy(crt_file)))
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
goto finally;
|
||||||
|
|
||||||
|
|
||||||
|
release:
|
||||||
|
crypter_free(self);
|
||||||
|
self = NULL;
|
||||||
|
|
||||||
|
finally:
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* src/ssl.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
|
||||||
|
*
|
||||||
|
* Project homepage: https://lowenware.com/aisl/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AISL_SSL_H_6F82B0BA_7C59_45BA_AF3B_C82A67C8585E
|
||||||
|
#define AISL_SSL_H_6F82B0BA_7C59_45BA_AF3B_C82A67C8585E
|
||||||
|
|
||||||
|
#include <aisl/types.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct ssl
|
||||||
|
{
|
||||||
|
char * key_file;
|
||||||
|
char * crt_file;
|
||||||
|
char * domain;
|
||||||
|
SSL_CTX * ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ssl * ssl_t;
|
||||||
|
|
||||||
|
|
||||||
|
ssl_t
|
||||||
|
ssl_new( const char * key_file, const char * crt_file, const char * domain );
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ssl_free( ssl_t self );
|
||||||
|
|
||||||
|
|
||||||
|
SSL_CTX *
|
||||||
|
ssl__new_context( const char * key_file, const char * crt_file, void * u_ptr );
|
||||||
|
|
||||||
|
#endif /* !AISL_SSL_H */
|
Loading…
Reference in New Issue