AC_CHECK_FUNCS(gettimeofday)
AC_CHECK_FUNCS(strlcpy)
+dnl gnutls
+want_gnutls="yes"
+have_gnutls="no"
+AC_ARG_ENABLE(gnutls,
+ AC_HELP_STRING(
+ [--disable-gnutls],
+ [disable gnutls support]
+ ),
+ [ want_gnutls=$enableval ]
+)
+
+if test "x$want_gnutls" = "xyes"; then
+ PKG_CHECK_MODULES([TLS2], [gnutls >= 2.0.0], [
+ AC_DEFINE(USE_GNUTLS2, 1, [Use GnuTLS 2 or higher])
+ have_gnutls2="yes"
+ ], [
+ have_gnutls2="no"
+ ])
+ PKG_CHECK_MODULES([TLS], [gnutls], [
+ AC_DEFINE(USE_GNUTLS, 1, [Use GnuTLS])
+ requirements_ecore_con="$requirements_ecore_con gnutls"
+ # no need to add it to req_ecore_ipc, since they
+ # depends on ecore_con anyway.
+ have_gnutls="yes"
+ ], [
+ have_gnutls="no"
+ ])
+fi
+
dnl openssl
want_openssl="yes"
have_openssl="no"
echo " Ecore_Desktop................: $have_ecore_desktop"
echo " Ecore_Con....................: $have_ecore_con"
if test "x$have_ecore_con" = "xyes" ; then
- echo " OpenSSL....................: $have_openssl"
+ echo -n " OpenSSL....................: $have_openssl"
+if test "x$have_gnutls" = "xyes" ; then
+ echo " (disabled)"
+else
+ echo
+fi
+ echo " GnuTLS.....................: $have_gnutls"
echo " CURL.......................: $have_curl"
fi
echo " Ecore_Ipc....................: $have_ecore_ipc"
if test "x$have_ecore_con" = "xyes" ; then
- echo " OpenSSL....................: $have_openssl"
+ echo -n " OpenSSL....................: $have_openssl"
+if test "x$have_gnutls" = "xyes" ; then
+ echo " (disabled)"
+else
+ echo
+fi
+ echo " GnuTLS.....................: $have_gnutls"
fi
echo " Ecore_Config.................: $have_ecore_config"
echo " Ecore_IMF....................: $have_ecore_imf"
-I$(top_builddir)/src/lib/ecore_con \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/ecore_con \
-@SSL_CFLAGS@ @CURL_CFLAGS@ @EINA_CFLAGS@
+@SSL_CFLAGS@ @CURL_CFLAGS@ @EINA_CFLAGS@ @TLS_CFLAGS@
if BUILD_ECORE_CON
ecore_con.c \
ecore_con_dns.c \
ecore_con_info.c \
+ecore_con_ssl.c \
ecore_con_url.c \
ecore_con_private.h
libecore_con_la_LIBADD = \
$(top_builddir)/src/lib/ecore/libecore.la \
-@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@
+@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@
libecore_con_la_LDFLAGS = -version-info @version_info@
ecore_con.c \
ecore_con_dns.c \
ecore_con_info.c \
+ecore_con_ssl.c \
ecore_con_url.c \
ecore_con_private.h
#include <config.h>
-#if USE_OPENSSL
-#include <time.h>
-#endif
-
#include "Ecore.h"
#include "ecore_private.h"
#include "Ecore_Con.h"
static Ecore_List *servers = NULL;
static int init_count = 0;
-#if USE_OPENSSL
-static int ssl_init_count = 0;
-static int _ecore_con_init_ssl(Ecore_Con_Server *svr);
-static int _ecore_con_shutdown_ssl(Ecore_Con_Server *svr);
-static int _ecore_con_free_ssl(Ecore_Con_Server *svr);
-
-# define INIT_SSL(svr) _ecore_con_init_ssl(svr)
-# define SHUTDOWN_SSL(svr) _ecore_con_shutdown_ssl(svr)
-# define FREE_SSL(svr) _ecore_con_free_ssl(svr)
-# define UNSET_SSL(svr) \
- do { \
- svr->ssl = NULL; \
- svr->ssl_ctx = NULL; \
- } while (0)
-#else
-# define INIT_SSL(svr) 0
-# define SHUTDOWN_SSL(svr) 0
-# define FREE_SSL(svr) 0
-# define UNSET_SSL(svr) 0
-#endif
-
#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
/* TODO Remember return value, if it fails, use gethostbyname() */
+ ecore_con_ssl_init();
ecore_con_dns_init();
ecore_con_info_init();
ecore_con_info_shutdown();
ecore_con_dns_shutdown();
+ ecore_con_ssl_shutdown();
ecore_shutdown();
svr->client_limit = -1;
svr->clients = ecore_list_new();
svr->ppid = getpid();
- /* Set ssl and ssl_ctx fields to NULL */
- UNSET_SSL(svr);
+ ecore_con_ssl_server_prepare(svr);
type = compl_type & ECORE_CON_TYPE;
_ecore_con_svr_handler, svr, NULL, NULL);
umask(pmode);
if (!svr->fd_handler) goto error;
-
- INIT_SSL(svr);
}
if (type == ECORE_CON_REMOTE_TCP)
if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
if (svr->write_buf) free(svr->write_buf);
if (svr->ip) free(svr->ip);
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
free(svr);
return NULL;
}
svr->reject_excess_clients = 0;
svr->client_limit = -1;
svr->clients = ecore_list_new();
- UNSET_SSL(svr);
+ ecore_con_ssl_server_prepare(svr);
type = compl_type & ECORE_CON_TYPE;
}
svr->path = strdup(buf);
if (!svr->path) goto error;
+
+ if (svr->type & ECORE_CON_SSL)
+ ecore_con_ssl_server_init(svr);
+
svr->fd_handler =
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
_ecore_con_cl_handler, svr, NULL, NULL);
if (svr->path) free(svr->path);
if (svr->fd >= 0) close(svr->fd);
if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
free(svr);
return NULL;
}
_ecore_con_client_flush(cl);
}
-/**
- * Returns if SSL support is available
- * @return 1 if SSL is available, 0 if it is not.
- * @ingroup Ecore_Con_Client_Group
- */
-EAPI int
-ecore_con_ssl_available_get(void)
-{
-#if USE_OPENSSL
- return 1;
-#else
- return 0;
-#endif
-}
-
static void
_ecore_con_server_free(Ecore_Con_Server *svr)
{
if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
unlink(svr->path);
if (svr->fd >= 0) close(svr->fd);
- SHUTDOWN_SSL(svr);
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
if (svr->name) free(svr->name);
if (svr->path) free(svr->path);
if (svr->ip) free(svr->ip);
free(cl);
}
-static int
-_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
-{
- Ecore_Con_Server *svr;
- int new_fd;
- struct sockaddr_in incoming;
- size_t size_in;
-
- svr = data;
- if (svr->dead) return 1;
- if (svr->delete_me) return 1;
- if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
- {
- if (ecore_list_count(svr->clients) >= svr->client_limit) return 1;
- }
- /* a new client */
- size_in = sizeof(struct sockaddr_in);
- new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
- if (new_fd >= 0)
- {
- Ecore_Con_Client *cl;
- char buf[64];
- uint32_t ip;
-
- if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
- {
- close(new_fd);
- return 1;
- }
-
- cl = calloc(1, sizeof(Ecore_Con_Client));
- if (!cl)
- {
- close(new_fd);
- return 1;
- }
- fcntl(new_fd, F_SETFL, O_NONBLOCK);
- fcntl(new_fd, F_SETFD, FD_CLOEXEC);
- cl->fd = new_fd;
- cl->server = svr;
- cl->fd_handler =
- ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
- _ecore_con_svr_cl_handler, cl, NULL, NULL);
- ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
- ecore_list_append(svr->clients, cl);
- if (!svr->path)
- {
- ip = incoming.sin_addr.s_addr;
- snprintf(buf, sizeof(buf),
- "%i.%i.%i.%i",
- (ip ) & 0xff,
- (ip >> 8 ) & 0xff,
- (ip >> 16) & 0xff,
- (ip >> 24) & 0xff);
- cl->ip = strdup(buf);
- }
- if (!cl->delete_me)
- {
- Ecore_Con_Event_Client_Add *e;
-
- e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
- if (e)
- {
- cl->event_count++;
- e->client = cl;
- ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
- _ecore_con_event_client_add_free, NULL);
- }
- }
- }
- return 1;
-}
-
-#if USE_OPENSSL
-/* Tries to connect an Ecore_Con_Server to an SSL host.
- * Returns 1 on success, -1 on fatal errors and 0 if the caller
- * should try again later.
- */
-static int
-svr_try_connect_ssl(Ecore_Con_Server *svr)
-{
- int res, ssl_err, flag = 0;
-
- if (!ssl_init_count)
- {
- SSL_library_init();
- SSL_load_error_strings();
- }
- ssl_init_count++;
-
- res = SSL_connect(svr->ssl);
- if (res == 1) return ECORE_CON_CONNECTED;
- ssl_err = SSL_get_error(svr->ssl, res);
-
- if (ssl_err == SSL_ERROR_NONE) return ECORE_CON_CONNECTED;
- if (ssl_err == SSL_ERROR_WANT_READ) flag = ECORE_FD_READ;
- else if (ssl_err == SSL_ERROR_WANT_WRITE) flag = ECORE_FD_WRITE;
- else return ECORE_CON_DISCONNECTED;
- if (svr->fd_handler)
- {
- if (flag) ecore_main_fd_handler_active_set(svr->fd_handler, flag);
- }
- return ECORE_CON_INPROGRESS;
-}
-#endif
-
static void
kill_server(Ecore_Con_Server *svr)
{
_ecore_con_svr_handler, svr, NULL, NULL);
if (!svr->fd_handler) goto error;
- if (INIT_SSL(svr))
- goto error;
-
return;
error:
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
kill_server(svr);
}
if (!svr->fd_handler) goto error;
svr->ip = strdup(net_info->ip);
- if (INIT_SSL(svr))
- goto error;
-
return;
error:
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
kill_server(svr);
}
goto error;
if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
{
- if (errno != EINPROGRESS)
- goto error;
- svr->connecting = 1;
- svr->fd_handler =
- ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
- _ecore_con_cl_handler, svr, NULL, NULL);
+ if (errno != EINPROGRESS)
+ goto error;
+ svr->connecting = 1;
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+ _ecore_con_cl_handler, svr, NULL, NULL);
}
else
svr->fd_handler =
- ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
- _ecore_con_cl_handler, svr, NULL, NULL);
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ _ecore_con_cl_handler, svr, NULL, NULL);
+
+ if (svr->type & ECORE_CON_SSL)
+ if (ecore_con_ssl_server_init(svr))
+ goto error;
if (!svr->fd_handler) goto error;
svr->ip = strdup(net_info->ip);
- if (INIT_SSL(svr))
- goto error;
-
return;
error:
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
kill_server(svr);
}
if (!svr->fd_handler) goto error;
svr->ip = strdup(net_info->ip);
- if (INIT_SSL(svr))
- goto error;
-
return;
error:
- FREE_SSL(svr);
+ ecore_con_ssl_server_shutdown(svr);
kill_server(svr);
}
/* returns 1 on success, 0 on failure */
static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
{
-#if USE_OPENSSL
- if (!svr->ssl)
- {
-#endif
- return svr_try_connect_plain(svr);
-#if USE_OPENSSL
- }
- else
- switch (svr_try_connect_ssl(svr)) {
+ if (!(svr->type & ECORE_CON_SSL))
+ return svr_try_connect_plain(svr);
+ else
+ {
+ switch (ecore_con_ssl_server_try(svr)) {
case ECORE_CON_CONNECTED:
return svr_try_connect_plain(svr);
case ECORE_CON_DISCONNECTED:
return ECORE_CON_DISCONNECTED;
default:
return ECORE_CON_INPROGRESS;
- }
-#endif
+ }
+ }
}
+static int
+_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Ecore_Con_Server *svr;
+ int new_fd;
+ struct sockaddr_in incoming;
+ size_t size_in;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (svr->delete_me) return 1;
+ if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
+ {
+ if (ecore_list_count(svr->clients) >= svr->client_limit) return 1;
+ }
+ /* a new client */
+ size_in = sizeof(struct sockaddr_in);
+
+ new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
+ if (new_fd >= 0)
+ {
+ Ecore_Con_Client *cl;
+ char buf[64];
+ uint32_t ip;
+
+ if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
+ {
+ close(new_fd);
+ return 1;
+ }
+
+ cl = calloc(1, sizeof(Ecore_Con_Client));
+ if (!cl)
+ {
+ close(new_fd);
+ return 1;
+ }
+
+ fcntl(new_fd, F_SETFL, O_NONBLOCK);
+ fcntl(new_fd, F_SETFD, FD_CLOEXEC);
+ cl->fd = new_fd;
+ cl->server = svr;
+
+ if ((svr->type & ECORE_CON_SSL) &&
+ (ecore_con_ssl_client_init(cl)))
+ {
+ close(new_fd);
+ ecore_con_ssl_client_shutdown(svr);
+ return 1;
+ }
+
+ cl->fd_handler =
+ ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
+ _ecore_con_svr_cl_handler, cl, NULL, NULL);
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
+ ecore_list_append(svr->clients, cl);
+ if (!svr->path)
+ {
+ ip = incoming.sin_addr.s_addr;
+ snprintf(buf, sizeof(buf),
+ "%i.%i.%i.%i",
+ (ip ) & 0xff,
+ (ip >> 8 ) & 0xff,
+ (ip >> 16) & 0xff,
+ (ip >> 24) & 0xff);
+ cl->ip = strdup(buf);
+ }
+ if (!cl->delete_me)
+ {
+ Ecore_Con_Event_Client_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
+ _ecore_con_event_client_add_free, NULL);
+ }
+ }
+ }
+ return 1;
+}
static int
_ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
{
Ecore_Con_Server *svr;
-#if USE_OPENSSL
- int ssl_err = SSL_ERROR_NONE;
-#endif
svr = data;
if (svr->dead) return 1;
for (;;)
{
- int num, lost_server;
- char buf[READBUFSIZ];
-
- lost_server = 0;
-#if USE_OPENSSL
- if (!svr->ssl)
- {
-#endif
- if ((num = read(svr->fd, buf, READBUFSIZ)) < 1)
- {
- lost_server = ((errno == EIO) ||
- (errno == EBADF) ||
- (errno == EPIPE) ||
- (errno == EINVAL) ||
- (errno == ENOSPC) ||
- (num == 0));
- /* is num == 0 is right - when the server closes us
- * off we will get this (as this is called when select
- * tells us there is data to read!)
- */
- }
-#if USE_OPENSSL
- }
- else
- {
- num = SSL_read(svr->ssl, buf, READBUFSIZ);
- if (num < 1)
- {
- ssl_err = SSL_get_error(svr->ssl, num);
- lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
- if (ssl_err == SSL_ERROR_SYSCALL)
- {
- if (num == 0) lost_server = 1;
- else
- {
- lost_server = ((errno == EIO) ||
- (errno == EBADF) ||
- (errno == EPIPE) ||
- (errno == EINVAL) ||
- (errno == ENOSPC) ||
- (errno == ECONNRESET));
- }
- }
- }
- else
- ssl_err = SSL_ERROR_NONE;
- }
-#endif
- if (num < 1)
- {
- if (inbuf)
- {
- if (!svr->delete_me)
- {
- Ecore_Con_Event_Server_Data *e;
-
- e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
- if (e)
- {
- svr->event_count++;
- e->server = svr;
- e->data = inbuf;
- e->size = inbuf_num;
- ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
- _ecore_con_event_server_data_free,
- NULL);
- }
- }
- }
- if (lost_server)
- {
- /* we lost our server! */
- kill_server(svr);
- return 1;
- }
- break;
- }
- else
- {
- inbuf = realloc(inbuf, inbuf_num + num);
- memcpy(inbuf + inbuf_num, buf, num);
- inbuf_num += num;
- }
+ int num;
+ int lost_server = 1;
+ char buf[READBUFSIZ];
+
+ if (!(svr->type & ECORE_CON_SSL))
+ {
+ if (((num = read(svr->fd, buf, READBUFSIZ)) < 0) &&
+ (errno == EAGAIN))
+ lost_server = 0;
+ }
+ else
+ if (!(num = ecore_con_ssl_server_read(svr, buf, READBUFSIZ)))
+ lost_server = 0;
+
+ if (num < 1)
+ {
+ if (inbuf && !svr->delete_me)
+ {
+ Ecore_Con_Event_Server_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
+ _ecore_con_event_server_data_free,
+ NULL);
+ }
+ }
+ if (lost_server) kill_server(svr);
+ break;
+ }
+
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
}
-#if USE_OPENSSL
- if (svr->fd_handler)
- {
- if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
- ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
- else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
- ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
- }
-#endif
+/* #if USE_OPENSSL */
+/* if (svr->fd_handler) */
+/* { */
+/* if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) */
+/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); */
+/* else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) */
+/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); */
+/* } */
+/* #endif */
}
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
{
{
unsigned char *inbuf = NULL;
int inbuf_num = 0;
+ int lost_client = 1;
for (;;)
{
int num;
errno = 0;
- num = read(cl->fd, buf, 65536);
+
+ if (!(cl->server->type & ECORE_CON_SSL))
+ {
+ if (((num = read(cl->fd, buf, 65536)) < 0) &&
+ (errno == EAGAIN))
+ lost_client = 0;
+ }
+ else
+ if (!(num = ecore_con_ssl_client_read(cl, buf, 65536)))
+ lost_client = 0;
+
if (num < 1)
{
- if (inbuf)
+ if (inbuf && !cl->delete_me)
{
- if (!cl->delete_me)
- {
- Ecore_Con_Event_Client_Data *e;
-
- e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
- if (e)
- {
- cl->event_count++;
- e->client = cl;
- e->data = inbuf;
- e->size = inbuf_num;
- ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
- _ecore_con_event_client_data_free,
- NULL);
- }
- }
+ Ecore_Con_Event_Client_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
+ _ecore_con_event_client_data_free,
+ NULL);
+ }
}
- if ((errno == EIO) || (errno == EBADF) ||
- (errno == EPIPE) || (errno == EINVAL) ||
- (errno == ENOSPC) || (num == 0)/* is num == 0 right? */)
+
+ if (lost_client)
{
if (!cl->delete_me)
{
_ecore_con_server_flush(Ecore_Con_Server *svr)
{
int count, num, lost_server = 0;
-#if USE_OPENSSL
- int ssl_err = SSL_ERROR_NONE;
-#endif
if (!svr->write_buf) return;
return;
num = svr->write_buf_size - svr->write_buf_offset;
-#if USE_OPENSSL
- if (!svr->ssl)
- {
-#endif
- count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
- if (count < 1)
- lost_server = (errno == EIO || errno == EBADF ||
- errno == EPIPE || errno == EINVAL || errno == ENOSPC);
-#if USE_OPENSSL
- }
- else
- {
- count = SSL_write(svr->ssl, svr->write_buf + svr->write_buf_offset, num);
- if (count < 1)
- {
- ssl_err = SSL_get_error(svr->ssl, count);
- lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN);
- }
- }
-#endif
+ if (!(svr->type & ECORE_CON_SSL))
+ count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
+ else
+ count = ecore_con_ssl_server_write(svr, svr->write_buf + svr->write_buf_offset, num);
- if (lost_server)
+ if (count < 0)
{
/* we lost our server! */
kill_server(svr);
return;
}
- if (count < 1)
- {
-#if USE_OPENSSL
- if (svr->fd_handler)
- {
- if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ)
- ecore_main_fd_handler_active_set(svr->fd_handler,
- ECORE_FD_READ);
- else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE)
- ecore_main_fd_handler_active_set(svr->fd_handler,
- ECORE_FD_WRITE);
- }
-#endif
- return;
- }
-
svr->write_buf_offset += count;
if (svr->write_buf_offset >= svr->write_buf_size)
{
if (!cl->buf) return;
num = cl->buf_size - cl->buf_offset;
- count = write(cl->fd, cl->buf + cl->buf_offset, num);
+ if (!(cl->server->type & ECORE_CON_SSL))
+ count = write(cl->fd, cl->buf + cl->buf_offset, num);
+ else
+ count = ecore_con_ssl_client_write(cl, cl->buf + cl->buf_offset, num);
if (count < 1)
{
if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
ecore_con_server_del(e->server);
free(e);
}
-
-#if USE_OPENSSL
-
-static int
-_ecore_con_init_ssl(Ecore_Con_Server *svr)
-{
- if (svr->type & ECORE_CON_SSL)
- {
- if (!ssl_init_count)
- {
- SSL_library_init();
- SSL_load_error_strings();
- }
- ssl_init_count++;
-
- switch (svr->type & ECORE_CON_SSL)
- {
- case ECORE_CON_USE_SSL2:
- if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
- return 1;
- break;
- case ECORE_CON_USE_SSL3:
- if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
- return 1;
- break;
- case ECORE_CON_USE_TLS:
- if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
- return 1;
- break;
- }
-
- if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
- return 1;
-
- SSL_set_fd(svr->ssl, svr->fd);
- }
- return 0;
-}
-
-static int
-_ecore_con_shutdown_ssl(Ecore_Con_Server *svr)
-{
- if (svr->ssl) SSL_shutdown(svr->ssl);
- return 0;
-}
-
-static int
-_ecore_con_free_ssl(Ecore_Con_Server *svr)
-{
- if (svr->ssl) SSL_free(svr->ssl);
- if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
- UNSET_SSL(svr);
-
- return 0;
-}
-
-#endif
#ifndef _ECORE_CON_PRIVATE_H
#define _ECORE_CON_PRIVATE_H
+#include "ecore_private.h"
#include "Ecore_Con.h"
#include "Ecore_Data.h"
#define ECORE_CON_TYPE 0x0f
#define ECORE_CON_SSL 0xf0
-#if USE_OPENSSL
-#include <openssl/ssl.h>
+#if USE_GNUTLS
+# include <gnutls/gnutls.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
#endif
#ifdef HAVE_CURL
#include <curl/curl.h>
typedef enum _Ecore_Con_State
{
- ECORE_CON_CONNECTED,
- ECORE_CON_DISCONNECTED,
- ECORE_CON_INPROGRESS
+ ECORE_CON_CONNECTED,
+ ECORE_CON_DISCONNECTED,
+ ECORE_CON_INPROGRESS
} Ecore_Con_State;
+typedef enum _Ecore_Con_Ssl_Error
+ {
+ ECORE_CON_SSL_ERROR_NONE = 0,
+ ECORE_CON_SSL_ERROR_NOT_SUPPORTED,
+ ECORE_CON_SSL_ERROR_INIT_FAILED,
+ ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED,
+ ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED
+ } Ecore_Con_Ssl_Error;
+
struct _Ecore_Con_Client
{
ECORE_MAGIC;
unsigned char *buf;
char *ip;
int event_count;
+#if USE_GNUTLS
+ gnutls_session session;
+#elif USE_OPENSSL
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+ int ssl_err;
+#endif
char dead : 1;
char delete_me : 1;
};
int event_count;
int client_limit;
pid_t ppid;
-#if USE_OPENSSL
+#if USE_GNUTLS
+ gnutls_session session;
+ gnutls_anon_client_credentials_t anoncred_c;
+ gnutls_anon_server_credentials_t anoncred_s;
+#elif USE_OPENSSL
SSL_CTX *ssl_ctx;
SSL *ssl;
+ int ssl_err;
#endif
char *ip;
char dead : 1;
int ecore_con_info_udp_connect(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
int ecore_con_info_udp_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
int ecore_con_info_mcast_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+/* from ecore_con_ssl.c */
+Ecore_Con_Ssl_Error ecore_con_ssl_init(void);
+Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void);
#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#if USE_GNUTLS
+# include <gnutls/gnutls.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
+#endif
+
+#include "ecore_con_private.h"
+
+static int _init_count = 0;
+
+#if USE_GNUTLS
+static int _client_connected = 0;
+
+# define SSL_SUFFIX(ssl_func) ssl_func##_gnutls
+# define _ECORE_CON_SSL_AVAILABLE 1
+
+#elif USE_OPENSSL
+# define SSL_SUFFIX(ssl_func) ssl_func##_openssl
+# define _ECORE_CON_SSL_AVAILABLE 2
+
+#else
+# define SSL_SUFFIX(ssl_func) ssl_func##_none
+# define _ECORE_CON_SSL_AVAILABLE 0
+
+#endif
+
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_init)(void);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_shutdown)(void);
+
+static void
+SSL_SUFFIX(_ecore_con_ssl_server_prepare)(Ecore_Con_Server *svr);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_server_init)(Ecore_Con_Server *svr);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(Ecore_Con_Server *svr);
+static Ecore_Con_State
+SSL_SUFFIX(_ecore_con_ssl_server_try)(Ecore_Con_Server *svr);
+static int
+SSL_SUFFIX(_ecore_con_ssl_server_read)(Ecore_Con_Server *svr, char *buf, int size);
+static int
+SSL_SUFFIX(_ecore_con_ssl_server_write)(Ecore_Con_Server *svr, char *buf, int size);
+
+static void
+SSL_SUFFIX(_ecore_con_ssl_client_prepare)(Ecore_Con_Client *cl);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_client_init)(Ecore_Con_Client *cl);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(Ecore_Con_Client *cl);
+static int
+SSL_SUFFIX(_ecore_con_ssl_client_read)(Ecore_Con_Client *cl, char *buf, int size);
+static int
+SSL_SUFFIX(_ecore_con_ssl_client_write)(Ecore_Con_Client *cl, char *buf, int size);
+
+/*
+ * General SSL API
+ */
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_init(void)
+{
+ if (!_init_count++)
+ SSL_SUFFIX(_ecore_con_ssl_init)();
+
+ return _init_count;
+}
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_shutdown(void)
+{
+ if (!--_init_count)
+ SSL_SUFFIX(_ecore_con_ssl_shutdown)();
+
+ return _init_count;
+}
+
+/**
+ * Returns if SSL support is available
+ * @return 1 if SSL is available, 0 if it is not.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI int
+ecore_con_ssl_available_get(void)
+{
+ return _ECORE_CON_SSL_AVAILABLE;
+}
+
+
+EAPI void
+ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
+{
+ SSL_SUFFIX(_ecore_con_ssl_server_prepare)(svr);
+}
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_server_init(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_init)(svr);
+}
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(svr);
+}
+
+EAPI Ecore_Con_State
+ecore_con_ssl_server_try(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_try)(svr);
+}
+
+EAPI int
+ecore_con_ssl_server_read(Ecore_Con_Server *svr, char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_read)(svr, buf, size);
+}
+
+EAPI int
+ecore_con_ssl_server_write(Ecore_Con_Server *svr, char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_write)(svr, buf, size);
+}
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_client_init(Ecore_Con_Client *cl)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_init)(cl);
+}
+
+EAPI Ecore_Con_Ssl_Error
+ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(cl);
+}
+
+EAPI int
+ecore_con_ssl_client_read(Ecore_Con_Client *cl, char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_read)(cl, buf, size);
+}
+
+EAPI int
+ecore_con_ssl_client_write(Ecore_Con_Client *cl, char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_write)(cl, buf, size);
+}
+
+#if USE_GNUTLS
+
+/*
+ * GnuTLS
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_gnutls(void)
+{
+ if (gnutls_global_init())
+ return ECORE_CON_SSL_ERROR_INIT_FAILED;
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_gnutls(void)
+{
+ gnutls_global_deinit();
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
+{
+ svr->session = NULL;
+ svr->anoncred_c = NULL;
+ return;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
+{
+ const int *proto = NULL;
+ gnutls_dh_params_t dh_params;
+ int ret;
+ const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
+ const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
+ const int tls_proto[] = {
+ GNUTLS_TLS1_0,
+ GNUTLS_TLS1_1,
+#ifdef USE_GNUTLS2
+ GNUTLS_TLS1_2,
+#endif
+ 0
+ };
+
+ switch (svr->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2: /* not supported because of security issues */
+ return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
+ case ECORE_CON_USE_SSL3:
+ proto = ssl3_proto;
+ break;
+ case ECORE_CON_USE_TLS:
+ proto = tls_proto;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+
+ gnutls_anon_allocate_client_credentials(&(svr->anoncred_c));
+ gnutls_init(&(svr->session), GNUTLS_CLIENT);
+ gnutls_set_default_priority(svr->session);
+ gnutls_kx_set_priority(svr->session, kx);
+ gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c);
+ gnutls_kx_set_priority(svr->session, kx);
+ gnutls_protocol_set_priority(svr->session, proto);
+ gnutls_dh_set_prime_bits(svr->session, 512);
+
+ gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
+
+ while ((ret = gnutls_handshake(svr->session)) < 0)
+ {
+ if ((ret == GNUTLS_E_AGAIN) ||
+ (ret == GNUTLS_E_INTERRUPTED))
+ continue;
+
+ _ecore_con_ssl_server_shutdown_gnutls(svr);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
+{
+ if (svr->session)
+ {
+ gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(svr->session);
+ }
+ if (svr->anoncred_c)
+ gnutls_anon_free_client_credentials(svr->anoncred_c);
+ _ecore_con_ssl_server_prepare_gnutls(svr);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_gnutls(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_CONNECTED;
+}
+
+static int
+_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_recv(svr->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static int
+_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_send(svr->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static void
+_ecore_con_ssl_client_prepare_gnutls(Ecore_Con_Client *cl)
+{
+ cl->session = NULL;
+ if (!_client_connected)
+ cl->server->anoncred_s = NULL;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
+{
+ const int *proto = NULL;
+ gnutls_dh_params_t dh_params;
+ int ret;
+ const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
+ const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
+ const int tls_proto[] = {
+ GNUTLS_TLS1_0,
+ GNUTLS_TLS1_1,
+#ifdef USE_GNUTLS2
+ GNUTLS_TLS1_2,
+#endif
+ 0
+ };
+
+ switch (cl->server->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2: /* not supported because of security issues */
+ return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
+ case ECORE_CON_USE_SSL3:
+ proto = ssl3_proto;
+ break;
+ case ECORE_CON_USE_TLS:
+ proto = tls_proto;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+
+ _client_connected++;
+ if (!cl->server->anoncred_s)
+ {
+ gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s));
+ gnutls_dh_params_init(&dh_params);
+ gnutls_dh_params_generate2(dh_params, 512);
+ gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
+ }
+
+ gnutls_init(&(cl->session), GNUTLS_SERVER);
+ gnutls_set_default_priority(cl->session);
+ gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->server->anoncred_s);
+
+ gnutls_kx_set_priority(cl->session, kx);
+
+ gnutls_protocol_set_priority(cl->session, proto);
+
+ gnutls_dh_set_prime_bits(cl->session, 512);
+
+ gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
+
+ while ((ret = gnutls_handshake(cl->session)) < 0)
+ {
+ if ((ret == GNUTLS_E_AGAIN) ||
+ (ret == GNUTLS_E_INTERRUPTED))
+ continue;
+
+ _ecore_con_ssl_client_shutdown_gnutls(cl);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
+{
+ if (cl->session)
+ {
+ gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(cl->session);
+ }
+ if (cl->server->anoncred_s && !--_client_connected)
+ gnutls_anon_free_server_credentials(cl->server->anoncred_s);
+ _ecore_con_ssl_client_prepare_gnutls(cl);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static int
+_ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_recv(cl->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static int
+_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_send(cl->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+#elif USE_OPENSSL
+
+/*
+ * OpenSSL
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_openssl(void)
+{
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_openssl(void)
+{
+ // FIXME nothing to do ?
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr)
+{
+ svr->ssl = NULL;
+ svr->ssl_ctx = NULL;
+ svr->ssl_err = SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
+{
+ switch (svr->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2:
+ /* Unsafe version of SSL */
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_SSL3:
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_TLS:
+ if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+ if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+ {
+ SSL_CTX_free(svr->ssl_ctx);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ SSL_set_fd(svr->ssl, svr->fd);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
+{
+ if (svr->ssl)
+ {
+ if (!SSL_shutdown(svr->ssl))
+ SSL_shutdown(svr->ssl);
+ SSL_free(svr->ssl);
+ }
+ if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+
+ _ecore_con_ssl_server_prepare_openssl(svr);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_openssl(Ecore_Con_Server *svr)
+{
+ int res, flag = 0;
+
+ if ((res = SSL_connect(svr->ssl)) == 1)
+ return ECORE_CON_CONNECTED;
+
+ svr->ssl_err = SSL_get_error(svr->ssl, res);
+
+ switch (svr->ssl_err)
+ {
+ case SSL_ERROR_NONE:
+ return ECORE_CON_CONNECTED;
+ case SSL_ERROR_WANT_READ:
+ flag = ECORE_FD_READ;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ flag = ECORE_FD_WRITE;
+ break;
+ default:
+ return ECORE_CON_DISCONNECTED;
+ }
+
+ if (svr->fd_handler && flag)
+ ecore_main_fd_handler_active_set(svr->fd_handler, flag);
+
+ return ECORE_CON_INPROGRESS;
+}
+
+static int
+_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, char *buf, int size)
+{
+ int num;
+
+ num = SSL_read(svr->ssl, buf, size);
+ svr->ssl_err = SSL_get_error(svr->ssl, num);
+
+ if (svr->fd_handler)
+ {
+ if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (svr->ssl_err == SSL_ERROR_SYSCALL) ||
+ (svr->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static int
+_ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, char *buf, int size)
+{
+ int num;
+
+ num = SSL_write(svr->ssl, buf, size);
+ svr->ssl_err = SSL_get_error(svr->ssl, num);
+
+ if (svr->fd_handler)
+ {
+ if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (svr->ssl_err == SSL_ERROR_SYSCALL) ||
+ (svr->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static void
+_ecore_con_ssl_client_prepare_openssl(Ecore_Con_Client *cl)
+{
+ cl->ssl = NULL;
+ cl->ssl_ctx = NULL;
+ cl->ssl_err = SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
+{
+ switch (cl->server->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2:
+ /* Unsafe version of SSL */
+ if (!(cl->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_SSL3:
+ if (!(cl->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_TLS:
+ if (!(cl->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+ if (!(cl->ssl = SSL_new(cl->ssl_ctx)))
+ {
+ SSL_CTX_free(cl->ssl_ctx);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ SSL_set_fd(cl->ssl, cl->fd);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
+{
+ if (cl->ssl)
+ {
+ if (!SSL_shutdown(cl->ssl))
+ SSL_shutdown(cl->ssl);
+ SSL_free(cl->ssl);
+ }
+ if (cl->ssl_ctx) SSL_CTX_free(cl->ssl_ctx);
+
+ _ecore_con_ssl_client_prepare_openssl(cl);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static int
+_ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, char *buf, int size)
+{
+ int num;
+
+ num = SSL_read(cl->ssl, buf, size);
+ cl->ssl_err = SSL_get_error(cl->ssl, num);
+
+ if (cl->fd_handler)
+ {
+ if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (cl->ssl_err == SSL_ERROR_SYSCALL) ||
+ (cl->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static int
+_ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, char *buf, int size)
+{
+ int num;
+
+ num = SSL_write(cl->ssl, buf, size);
+ cl->ssl_err = SSL_get_error(cl->ssl, num);
+
+ if (cl->fd_handler)
+ {
+ if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (cl->ssl_err == SSL_ERROR_SYSCALL) ||
+ (cl->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+#else
+
+/*
+ * No Ssl
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_none(void)
+{
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_none(void)
+{
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr)
+{
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_DISCONNECTED;
+}
+
+static int
+_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr, char *buf, int size)
+{
+ return -1;
+}
+
+static int
+_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, char *buf, int size)
+{
+ return -1;
+}
+
+static void
+_ecore_con_ssl_client_prepare_none(Ecore_Con_Client *cl)
+{
+ return;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static int
+_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl, char *buf, int size)
+{
+ return -1;
+}
+
+static int
+_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl, char *buf, int size)
+{
+ return -1;
+}
+
+#endif
#include "Ecore_Data.h"
-#if USE_OPENSSL
-#include <openssl/ssl.h>
+#if USE_GNUTLS_OPENSSL
+# include <gnutls/openssl.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
#endif
#define ECORE_MAGIC_IPC_SERVER 0x87786556