giant cleanups/rewrites which are unnoticeable to users:
authordiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 18 Sep 2010 19:26:05 +0000 (19:26 +0000)
committerdiscomfitor <discomfitor@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 18 Sep 2010 19:26:05 +0000 (19:26 +0000)
*client->server renamed client->host_server to clarify ambiguity
*ecore_con_ssl_client_prepare.* killed off because it was useless and wrong
*openssl generates only one SSL_CTX per server now instead of a new one for each client, which is broken/unnecessary/wasteful
**as a result, certificate loading is now only done once
**additionally this will save a very large amount of memory and avoid unnecessary/broken refcounting
*ecore_con_ssl_server_prepare.* rewritten to actually be useful instead of just a lazy way to null pointers
**all SSL_CTX code now goes here^
*some formatting fixes
*internal function renames

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@52422 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_con/ecore_con.c
src/lib/ecore_con/ecore_con_private.h
src/lib/ecore_con/ecore_con_ssl.c

index 5ef893f..2fbf0e8 100644 (file)
@@ -51,7 +51,7 @@ static void      _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *info);
 static void      _ecore_con_server_free(Ecore_Con_Server *svr);
 static void      _ecore_con_client_free(Ecore_Con_Client *cl);
 
-static Eina_Bool _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler);
 static Eina_Bool _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
 static Eina_Bool _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
 static Eina_Bool _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
@@ -220,7 +220,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
    svr->client_limit = -1;
    svr->clients = NULL;
    svr->ppid = getpid();
-   ecore_con_ssl_server_prepare(svr);
+   ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL);
 
    type = compl_type & ECORE_CON_TYPE;
 
@@ -228,7 +228,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
        (type == ECORE_CON_LOCAL_SYSTEM) ||
        (type == ECORE_CON_LOCAL_ABSTRACT))
       /* Local */
-      if (!ecore_con_local_listen(svr, _ecore_con_svr_handler, svr))
+      if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr))
          goto error;
 
    if ((type == ECORE_CON_REMOTE_TCP) ||
@@ -310,8 +310,8 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
    Ecore_Con_Type type;
 
    if (!name)
-      return NULL;  /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
-
+      return NULL;
+   /* local  user   socket: FILE:   ~/.ecore/[name]/[port] */
    /* local  system socket: FILE:   /tmp/.ecore_service|[name]|[port] */
    /* remote system socket: TCP/IP: [name]:[port] */
    svr = calloc(1, sizeof(Ecore_Con_Server));
@@ -329,7 +329,7 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
    svr->reject_excess_clients = EINA_FALSE;
    svr->clients = NULL;
    svr->client_limit = -1;
-   ecore_con_ssl_server_prepare(svr);
+   ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL);
 
    type = compl_type & ECORE_CON_TYPE;
 
@@ -736,8 +736,8 @@ ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size)
       ecore_main_fd_handler_active_set(
          cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
 
-   if(cl->server && ((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP))
-      sendto(cl->server->fd, data, size, 0, (struct sockaddr *)cl->client_addr,
+   if(cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP))
+      sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr,
              cl->client_addr_len);
    else if (cl->buf)
      {
@@ -781,7 +781,7 @@ ecore_con_client_server_get(Ecore_Con_Client *cl)
         return NULL;
      }
 
-   return cl->server;
+   return cl->host_server;
 }
 
 /**
@@ -800,9 +800,9 @@ ecore_con_client_del(Ecore_Con_Client *cl)
         return NULL;
      }
 
-   if (cl->client_addr && cl->server &&
-      (((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP) ||
-       ((cl->server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))
+   if (cl->client_addr && cl->host_server &&
+      (((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP) ||
+       ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))
       free(cl->client_addr);
 
    data = cl->data;
@@ -819,9 +819,9 @@ ecore_con_client_del(Ecore_Con_Client *cl)
      }
    else
      {
-        if (cl->server)
-           cl->server->clients = eina_list_remove(
-                 cl->server->clients, cl);
+        if (cl->host_server)
+           cl->host_server->clients = eina_list_remove(
+                 cl->host_server->clients, cl);
 
         _ecore_con_client_free(cl);
      }
@@ -1034,8 +1034,7 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
    EINA_LIST_FREE(svr->clients, cl)
    _ecore_con_client_free(cl);
    if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
-      unlink(
-         svr->path);
+      unlink(svr->path);
 
    if (svr->fd >= 0)
       close(svr->fd);
@@ -1161,7 +1160,7 @@ _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *net_info)
       goto error;
 
    svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
-                                _ecore_con_svr_handler, svr, NULL, NULL);
+                                _ecore_con_svr_tcp_handler, svr, NULL, NULL);
    if (!svr->fd_handler)
       goto error;
 
@@ -1481,7 +1480,7 @@ _ecore_con_pretty_ip(struct sockaddr *client_addr, socklen_t size)
 }
 
 static Eina_Bool
-_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+_ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
 {
    Ecore_Con_Server *svr;
    Ecore_Con_Client *cl = NULL;
@@ -1521,7 +1520,7 @@ _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
    fcntl(new_fd, F_SETFL, O_NONBLOCK);
    fcntl(new_fd, F_SETFD, FD_CLOEXEC);
    cl->fd = new_fd;
-   cl->server = svr;
+   cl->host_server = svr;
 
    if ((svr->type & ECORE_CON_SSL) && (ecore_con_ssl_client_init(cl)))
      {
@@ -1756,7 +1755,7 @@ _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
                   cl->buf = NULL;
                   cl->fd = 0;
                   cl->fd_handler = NULL;
-                  cl->server = svr;
+                  cl->host_server = svr;
                   cl->client_addr = calloc(1, client_addr_len);
                   cl->client_addr_len = client_addr_len;
                   if(!cl->client_addr)
@@ -1861,7 +1860,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl)
 
         errno = 0;
 
-        if (!(cl->server->type & ECORE_CON_SSL))
+        if (!(cl->host_server->type & ECORE_CON_SSL))
           {
              if ((num = read(cl->fd, buf, READBUFSIZ)) <= 0)
                 if ((num < 0) && (errno == EAGAIN))
@@ -1997,7 +1996,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl)
       return;
 
    num = cl->buf_size - cl->buf_offset;
-   if (!(cl->server->type & ECORE_CON_SSL))
+   if (!(cl->host_server->type & ECORE_CON_SSL))
       count = write(
             cl->fd, cl->buf + cl->buf_offset, num);
    else
@@ -2083,9 +2082,9 @@ _ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
       free(e->data);
 
    if (((e->client->event_count == 0) && (e->client->delete_me)) ||
-       ((e->client->server &&
-         ((e->client->server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
-          (e->client->server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
+       ((e->client->host_server &&
+         ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
+          (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
       ecore_con_client_del(e->client);
 
    free(e);
index 85053f3..e3fd060 100644 (file)
@@ -79,7 +79,7 @@ struct _Ecore_Con_Client
 {
    ECORE_MAGIC;
    int fd;
-   Ecore_Con_Server *server;
+   Ecore_Con_Server *host_server;
    void *data;
    Ecore_Fd_Handler *fd_handler;
    int buf_size;
@@ -92,7 +92,6 @@ struct _Ecore_Con_Client
 #if USE_GNUTLS
    gnutls_session session;
 #elif USE_OPENSSL
-   SSL_CTX *ssl_ctx;
    SSL *ssl;
    int ssl_err;
 #endif
@@ -129,7 +128,7 @@ struct _Ecore_Con_Server
 #endif
    char *ip;
    Eina_Bool dead : 1;
-   Eina_Bool created : 1;
+   Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
    Eina_Bool connecting : 1;
    Eina_Bool reject_excess_clients : 1;
    Eina_Bool delete_me : 1;
@@ -215,7 +214,7 @@ Eina_Bool           ecore_con_ssl_server_cert_add(const char *cert);
 Eina_Bool           ecore_con_ssl_client_cert_add(const char *cert_file,
                                                   const char *crl_file,
                                                   const char *key_file);
-void                ecore_con_ssl_server_prepare(Ecore_Con_Server *svr);
+Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type);
 Ecore_Con_Ssl_Error ecore_con_ssl_server_init(Ecore_Con_Server *svr);
 Ecore_Con_Ssl_Error ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr);
 Ecore_Con_State     ecore_con_ssl_server_try(Ecore_Con_Server *svr);
index e259461..0749af8 100644 (file)
@@ -92,8 +92,7 @@ static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_client_cert_add) (const char *
                                                              key_file);
 static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (const char *cert);
 
-static void      SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server *
-                                                            svr);
+static Ecore_Con_Ssl_Error  SSL_SUFFIX(_ecore_con_ssl_server_prepare)(Ecore_Con_Server *svr, int ssl_type);
 static Ecore_Con_Ssl_Error
                  SSL_SUFFIX(_ecore_con_ssl_server_init) (Ecore_Con_Server * svr);
 static Ecore_Con_Ssl_Error
@@ -109,9 +108,6 @@ static int
                                          svr,
                                          unsigned 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
@@ -172,10 +168,10 @@ ecore_con_ssl_available_get(void)
 }
 
 
-void
-ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
+Ecore_Con_Ssl_Error
+ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type)
 {
-        SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr);
+   return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type);
 }
 
 Ecore_Con_Ssl_Error
@@ -276,12 +272,11 @@ _ecore_con_ssl_shutdown_gnutls(void)
    return ECORE_CON_SSL_ERROR_NONE;
 }
 
-static void
-_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr __UNUSED__, int ssl_type __UNUSED__)
 {
-   svr->session = NULL;
-   svr->anoncred_c = NULL;
-   return;
+
+   return ECORE_CON_SSL_ERROR_NONE;
 }
 
 /* Tries to connect an Ecore_Con_Server to an SSL host.
@@ -431,7 +426,8 @@ _ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
    else if (svr->anoncred_c)
       gnutls_anon_free_client_credentials(svr->anoncred_c);
 
-   _ecore_con_ssl_server_prepare_gnutls(svr);
+   svr->session = NULL;
+   svr->anoncred_c = NULL;
 
    return ECORE_CON_SSL_ERROR_NONE;
 }
@@ -479,16 +475,6 @@ _ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, unsigned char *buf,
    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;
-        cl->server->cert = NULL;
-     }
-}
 
 static Ecore_Con_Ssl_Error
 _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
@@ -516,7 +502,7 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
         GNUTLS_SSL3, 
         0 };
 
-   switch (cl->server->type & ECORE_CON_SSL)
+   switch (cl->host_server->type & ECORE_CON_SSL)
      {
       case ECORE_CON_USE_SSL2: /* not supported because of security issues */
       case ECORE_CON_USE_SSL2 | ECORE_CON_LOAD_CERT: /* not supported because of security issues */
@@ -548,26 +534,26 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(dh_params, 1024));
 
    if ((client_cert) && (client_cert->cert) &&
-       ((cl->server->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT)
+       ((cl->host_server->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT)
      {
-        cl->server->cert = client_cert->cert;
+        cl->host_server->cert = client_cert->cert;
         client_cert->count++;
-        gnutls_certificate_set_dh_params(cl->server->cert, dh_params);
+        gnutls_certificate_set_dh_params(cl->host_server->cert, dh_params);
      }
 
-   if ((!cl->server->anoncred_s) && (!cl->server->cert))
+   if ((!cl->host_server->anoncred_s) && (!cl->host_server->cert))
      {
-        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s)));
-        gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
+        SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&(cl->host_server->anoncred_s)));
+        gnutls_anon_set_server_dh_params(cl->host_server->anoncred_s, dh_params);
      }
 
    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&(cl->session), GNUTLS_SERVER));
    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_set_default_priority(cl->session));
-   if (cl->server->cert)
+   if (cl->host_server->cert)
      {
         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session,
                                GNUTLS_CRD_CERTIFICATE,
-                               cl->server->cert));
+                               cl->host_server->cert));
         gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
      }
    else
@@ -575,7 +561,7 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
         const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_kx_set_priority(cl->session, kx));
         SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON,
-                             cl->server->anoncred_s));
+                             cl->host_server->anoncred_s));
      }
 
    SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_protocol_set_priority(cl->session, proto));
@@ -607,10 +593,10 @@ _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
         gnutls_deinit(cl->session);
      }
 
-   if (cl->server->anoncred_s && !--_client_connected)
-      gnutls_anon_free_server_credentials(cl->server->anoncred_s);
+   if (cl->host_server->anoncred_s && !--_client_connected)
+      gnutls_anon_free_server_credentials(cl->host_server->anoncred_s);
 
-   if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
+   if (((cl->host_server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
        (client_cert) &&
        (client_cert->cert) && (--client_cert->count < 1))
      {
@@ -619,7 +605,12 @@ _ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
         client_cert = NULL;
      }
 
-   _ecore_con_ssl_client_prepare_gnutls(cl);
+   cl->session = NULL;
+   if (!_client_connected)
+     {
+        cl->host_server->anoncred_s = NULL;
+        cl->host_server->cert = NULL;
+     }
 
    return ECORE_CON_SSL_ERROR_NONE;
 }
@@ -735,59 +726,86 @@ _ecore_con_ssl_shutdown_openssl(void)
    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)
+_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, int ssl_type)
 {
    long options;
 
-   switch (svr->type & ECORE_CON_SSL)
+   switch (ssl_type)
      {
       case ECORE_CON_USE_SSL2:
       case ECORE_CON_USE_SSL2 | ECORE_CON_LOAD_CERT:
          /* Unsafe version of SSL */
-         SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())));
+         if (!svr->created)
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())));
+         else
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv2_server_method())));
          break;
 
       case ECORE_CON_USE_SSL3:
       case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
+         if (!svr->created)
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
+         else
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
          break;
 
       case ECORE_CON_USE_TLS:
       case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
+         if (!svr->created)
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
+         else
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
          break;
 
       case ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS:
       case ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
+         if (!svr->created)
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
+         else
+           SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
          options = SSL_CTX_get_options(svr->ssl_ctx);
          SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2);
          break;
 
       default:
-         return ECORE_CON_SSL_ERROR_NONE;
+         break;
      }
-     
-   SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
 
-   if ((server_cert) && (server_cert->cert) &&
-       ((svr->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT)
-     {
-        //FIXME: just log and go on without cert if loading fails?
+   if ((server_cert) && (server_cert->cert) && (!svr->created) &&
+       ((ssl_type & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT))
+     { /* this is a client */
         SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, server_cert->cert) < 1);
 
         server_cert->count++;
      }
 
+   if ((client_cert) && (client_cert->cert) && (private_key->key) && (svr->created) &&
+       ((ssl_type & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT))
+     { /* this is a server */
+        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, client_cert->cert) < 1);
+        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, private_key->key) < 1);
+        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1);
+
+        client_cert->count++;
+        private_key->count++;
+     }
+
+     return ECORE_CON_SSL_ERROR_NONE;
+
+error:
+   if (svr->ssl_ctx)
+     SSL_CTX_free(svr->ssl_ctx);
+
+   ERR("openssl error: %s", ERR_reason_error_string(ERR_get_error()));
+   return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
+{
+   SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
+
    SSL_set_connect_state(svr->ssl);
    SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
 
@@ -862,7 +880,9 @@ _ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
    if (svr->ssl_ctx)
       SSL_CTX_free(svr->ssl_ctx);
 
-   _ecore_con_ssl_server_prepare_openssl(svr);
+   svr->ssl = NULL;
+   svr->ssl_ctx = NULL;
+   svr->ssl_err = SSL_ERROR_NONE;
 
    return ECORE_CON_SSL_ERROR_NONE;
 }
@@ -971,69 +991,20 @@ _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf,
    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)
 {
-   long options;
-   
-   switch (cl->server->type & ECORE_CON_SSL)
-     {
-      case ECORE_CON_USE_SSL2:
-      case ECORE_CON_USE_SSL2 | ECORE_CON_LOAD_CERT:
-         /* Unsafe version of SSL */
-         SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl_ctx = SSL_CTX_new(SSLv2_server_method())));
-
-      case ECORE_CON_USE_SSL3:
-      case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
-         break;
-
-      case ECORE_CON_USE_TLS:
-      case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
-         break;
-
-      case ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS:
-      case ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
-         SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
-         options = SSL_CTX_get_options(cl->ssl_ctx);
-         SSL_CTX_set_options(cl->ssl_ctx, options | SSL_OP_NO_SSLv2);
-         break;
-
-      default:
-         return ECORE_CON_SSL_ERROR_NONE;
-     }
-   SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->ssl_ctx)));
-
-   if ((client_cert) && (client_cert->cert) && (private_key->key) &&
-       ((cl->server->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT)
-     {
-        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(cl->ssl_ctx, client_cert->cert) < 1);
-        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(cl->ssl_ctx, private_key->key) < 1);
-        SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(cl->ssl_ctx) < 1);
-
-        client_cert->count++;
-        private_key->count++;
-     }
+   SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
 
    SSL_set_accept_state(cl->ssl);
    SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
+   SSL_ERROR_CHECK_GOTO_ERROR(SSL_do_handshake(cl->ssl) < 1);
    
    return ECORE_CON_SSL_ERROR_NONE;
 
 error:
    if (cl->ssl)
      SSL_free(cl->ssl);
-   if (cl->ssl_ctx)
-     SSL_CTX_free(cl->ssl_ctx);
 
    ERR("openssl error: %s", ERR_reason_error_string(ERR_get_error()));
    return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
@@ -1115,27 +1086,8 @@ _ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
         SSL_free(cl->ssl);
      }
 
-   if (cl->ssl_ctx)
-     {
-        SSL_CTX_free(cl->ssl_ctx);
-        if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
-            (client_cert) && (client_cert->cert) && (--client_cert->count < 1))
-          {
-             X509_free(client_cert->cert);
-             free(client_cert);
-             client_cert = NULL;
-          }
-
-        if (((cl->server->type & ECORE_CON_TYPE) & ECORE_CON_LOAD_CERT) &&
-            (private_key) && (private_key->key) && (--private_key->count < 1))
-          {
-             EVP_PKEY_free(private_key->key);
-             free(private_key);
-             private_key = NULL;
-          }
-     }
-
-   _ecore_con_ssl_client_prepare_openssl(cl);
+   cl->ssl = NULL;
+   cl->ssl_err = SSL_ERROR_NONE;
 
    return ECORE_CON_SSL_ERROR_NONE;
 }
@@ -1224,9 +1176,10 @@ _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_prepare_none(Ecore_Con_Server *svr __UNUSED__, int ssl_type __UNUSED__)
 {
+   return ECORE_CON_SSL_ERROR_NONE;
 }
 
 static Ecore_Con_Ssl_Error
@@ -1271,12 +1224,6 @@ _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, unsigned char *buf,
    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)
 {