yet another ecore_con overhaul!

*internal function rename
*******finally fix ssl handshaking to be non-blocking


SVN revision: 52665
This commit is contained in:
Mike Blumenkrantz 2010-09-24 04:15:42 +00:00
parent e7392af747
commit 60b4269b5f
3 changed files with 204 additions and 119 deletions

View File

@ -1266,7 +1266,7 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
} }
static void static void
kill_server(Ecore_Con_Server *svr) _ecore_con_server_kill(Ecore_Con_Server *svr)
{ {
if (!svr->delete_me) if (!svr->delete_me)
{ {
@ -1385,7 +1385,7 @@ _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *net_info)
error: error:
ecore_con_ssl_server_shutdown(svr); ecore_con_ssl_server_shutdown(svr);
kill_server(svr); _ecore_con_server_kill(svr);
} }
static void static void
@ -1461,7 +1461,7 @@ _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *net_info)
error: error:
ecore_con_ssl_server_shutdown(svr); ecore_con_ssl_server_shutdown(svr);
kill_server(svr); _ecore_con_server_kill(svr);
} }
static void static void
@ -1523,8 +1523,13 @@ _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
_ecore_con_cl_handler, svr, NULL, NULL); _ecore_con_cl_handler, svr, NULL, NULL);
if ((svr->type & ECORE_CON_SSL) && (ecore_con_ssl_server_init(svr))) if (svr->type & ECORE_CON_SSL)
goto error; {
svr->handshaking = EINA_TRUE;
svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
if (ecore_con_ssl_server_init(svr))
goto error;
}
if (!svr->fd_handler) if (!svr->fd_handler)
goto error; goto error;
@ -1535,7 +1540,7 @@ _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
error: error:
ecore_con_ssl_server_shutdown(svr); ecore_con_ssl_server_shutdown(svr);
kill_server(svr); _ecore_con_server_kill(svr);
} }
static void static void
@ -1586,7 +1591,7 @@ _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info)
error: error:
ecore_con_ssl_server_shutdown(svr); ecore_con_ssl_server_shutdown(svr);
kill_server(svr); _ecore_con_server_kill(svr);
} }
static Ecore_Con_State static Ecore_Con_State
@ -1616,7 +1621,7 @@ svr_try_connect_plain(Ecore_Con_Server *svr)
if (so_err != 0) if (so_err != 0)
{ {
/* we lost our server! */ /* we lost our server! */
kill_server(svr); _ecore_con_server_kill(svr);
return ECORE_CON_DISCONNECTED; return ECORE_CON_DISCONNECTED;
} }
@ -1658,7 +1663,7 @@ static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
return svr_try_connect_plain(svr); return svr_try_connect_plain(svr);
case ECORE_CON_DISCONNECTED: case ECORE_CON_DISCONNECTED:
kill_server(svr); _ecore_con_server_kill(svr);
return ECORE_CON_DISCONNECTED; return ECORE_CON_DISCONNECTED;
default: default:
@ -1740,8 +1745,13 @@ _ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
cl->fd = new_fd; cl->fd = new_fd;
cl->host_server = svr; cl->host_server = svr;
if ((svr->type & ECORE_CON_SSL) && (ecore_con_ssl_client_init(cl))) if (svr->type & ECORE_CON_SSL)
goto error; {
cl->handshaking = EINA_TRUE;
cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
if (ecore_con_ssl_client_init(cl))
goto error;
}
cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
_ecore_con_svr_cl_handler, cl, NULL, NULL); _ecore_con_svr_cl_handler, cl, NULL, NULL);
@ -1751,7 +1761,7 @@ _ecore_con_svr_tcp_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
if (!svr->path) if (!svr->path)
cl->ip = _ecore_con_pretty_ip((struct sockaddr *)&incoming, size_in); cl->ip = _ecore_con_pretty_ip((struct sockaddr *)&incoming, size_in);
if (!cl->delete_me) if ((!cl->delete_me) && (!cl->handshaking))
{ {
Ecore_Con_Event_Client_Add *e; Ecore_Con_Event_Client_Add *e;
@ -1818,7 +1828,7 @@ _ecore_con_cl_read(Ecore_Con_Server *svr)
} }
if (lost_server) if (lost_server)
kill_server(svr); _ecore_con_server_kill(svr);
break; break;
} }
@ -1851,6 +1861,17 @@ _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
if (svr->delete_me) if (svr->delete_me)
return ECORE_CALLBACK_RENEW; return ECORE_CALLBACK_RENEW;
if (svr->handshaking)
{
if (ecore_con_ssl_server_init(svr))
{
ERR("ssl handshaking failed!");
ecore_main_fd_handler_del(svr->fd_handler);
close(svr->fd);
}
return ECORE_CALLBACK_RENEW;
}
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
_ecore_con_cl_read(svr); _ecore_con_cl_read(svr);
else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
@ -1912,7 +1933,7 @@ _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
else if ((errno == EIO) || (errno == EBADF) || else if ((errno == EIO) || (errno == EBADF) ||
(errno == EPIPE) || (errno == EINVAL) || (errno == EPIPE) || (errno == EINVAL) ||
(errno == ENOSPC) || (errno == ECONNREFUSED)) (errno == ENOSPC) || (errno == ECONNREFUSED))
kill_server(svr); _ecore_con_server_kill(svr);
} }
else if (ecore_main_fd_handler_active_get(fd_handler, else if (ecore_main_fd_handler_active_get(fd_handler,
ECORE_FD_WRITE)) ECORE_FD_WRITE))
@ -2153,6 +2174,17 @@ _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
if (cl->delete_me) if (cl->delete_me)
return ECORE_CALLBACK_RENEW; return ECORE_CALLBACK_RENEW;
if (cl->handshaking)
{
if (ecore_con_ssl_client_init(cl))
{
ERR("ssl handshaking failed!");
ecore_main_fd_handler_del(cl->fd_handler);
close(cl->fd);
}
return ECORE_CALLBACK_RENEW;
}
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
_ecore_con_svr_cl_read(cl); _ecore_con_svr_cl_read(cl);
@ -2189,7 +2221,7 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
if (count < 1) if (count < 1)
{ {
/* we lost our server! */ /* we lost our server! */
kill_server(svr); _ecore_con_server_kill(svr);
return; return;
} }

View File

@ -75,6 +75,13 @@ typedef enum _Ecore_Con_Ssl_Error
ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED
} Ecore_Con_Ssl_Error; } Ecore_Con_Ssl_Error;
typedef enum _Ecore_Con_Ssl_Handshake
{
ECORE_CON_SSL_STATE_DONE = 0,
ECORE_CON_SSL_STATE_HANDSHAKING,
ECORE_CON_SSL_STATE_INIT
} Ecore_Con_Ssl_State;
struct _Ecore_Con_Client struct _Ecore_Con_Client
{ {
ECORE_MAGIC; ECORE_MAGIC;
@ -98,6 +105,8 @@ struct _Ecore_Con_Client
SSL *ssl; SSL *ssl;
int ssl_err; int ssl_err;
#endif #endif
Eina_Bool handshaking : 1;
Ecore_Con_Ssl_State ssl_state;
Eina_Bool dead : 1; Eina_Bool dead : 1;
Eina_Bool delete_me : 1; Eina_Bool delete_me : 1;
}; };
@ -139,6 +148,8 @@ struct _Ecore_Con_Server
Eina_Bool dead : 1; Eina_Bool dead : 1;
Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */ Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
Eina_Bool connecting : 1; Eina_Bool connecting : 1;
Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */
Ecore_Con_Ssl_State ssl_state;
Eina_Bool reject_excess_clients : 1; Eina_Bool reject_excess_clients : 1;
Eina_Bool delete_me : 1; Eina_Bool delete_me : 1;
}; };

View File

@ -362,56 +362,66 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
GNUTLS_SSL3, GNUTLS_SSL3,
0 0
}; };
switch (svr->ssl_state)
if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
switch (svr->type & ECORE_CON_SSL)
{ {
case ECORE_CON_USE_SSL3: case ECORE_CON_SSL_STATE_DONE:
case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: return ECORE_CON_SSL_ERROR_NONE;
proto = ssl3_proto; case ECORE_CON_SSL_STATE_INIT:
break; if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
case ECORE_CON_USE_TLS: switch (svr->type & ECORE_CON_SSL)
case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: {
proto = tls_proto; case ECORE_CON_USE_SSL3:
break; case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
proto = ssl3_proto;
break;
case ECORE_CON_USE_MIXED: case ECORE_CON_USE_TLS:
case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
proto = mixed_proto; proto = tls_proto;
break; break;
default: case ECORE_CON_USE_MIXED:
return ECORE_CON_SSL_ERROR_NONE; case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
} proto = mixed_proto;
break;
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT)); default:
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_set_default_priority(svr->session)); return ECORE_CON_SSL_ERROR_NONE;
}
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT));
//SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_set_default_priority(svr->session));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c));
if (!((svr->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT))
{
int kx[] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
int cipher[] = { GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC, 0 };
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_cipher_set_priority(svr->session, cipher));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_kx_set_priority(svr->session, kx));
}
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_protocol_set_priority(svr->session, proto)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_compression_set_priority(svr->session, compress)); //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c));
if (!((svr->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT))
{
int kx[] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
int cipher[] = { GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC, 0 };
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_cipher_set_priority(svr->session, cipher));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_kx_set_priority(svr->session, kx));
}
gnutls_dh_set_prime_bits(svr->session, 512); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_protocol_set_priority(svr->session, proto));
gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_compression_set_priority(svr->session, compress));
do gnutls_dh_set_prime_bits(svr->session, 512);
{ gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
case ECORE_CON_SSL_STATE_HANDSHAKING:
ret = gnutls_handshake(svr->session); ret = gnutls_handshake(svr->session);
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
} while (ret < 0); if (!ret)
{
svr->handshaking = EINA_FALSE;
svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
}
default:
break;
}
return ECORE_CON_SSL_ERROR_NONE; return ECORE_CON_SSL_ERROR_NONE;
@ -581,57 +591,68 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
GNUTLS_TLS1_0, GNUTLS_TLS1_0,
GNUTLS_SSL3, GNUTLS_SSL3,
0 }; 0 };
switch (cl->ssl_state)
if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
switch (cl->host_server->type & ECORE_CON_SSL)
{ {
case ECORE_CON_USE_SSL3: case ECORE_CON_SSL_STATE_DONE:
case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: return ECORE_CON_SSL_ERROR_NONE;
proto = ssl3_proto; case ECORE_CON_SSL_STATE_INIT:
break; if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */
return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
case ECORE_CON_USE_TLS: switch (cl->host_server->type & ECORE_CON_SSL)
case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: {
proto = tls_proto; case ECORE_CON_USE_SSL3:
break; case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
proto = ssl3_proto;
break;
case ECORE_CON_USE_MIXED: case ECORE_CON_USE_TLS:
case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
proto = mixed_proto; proto = tls_proto;
break; break;
default: case ECORE_CON_USE_MIXED:
return ECORE_CON_SSL_ERROR_NONE; case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
} proto = mixed_proto;
break;
_client_connected++; default:
return ECORE_CON_SSL_ERROR_NONE;
}
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER)); _client_connected++;
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_set_default_priority(cl->session));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_protocol_set_priority(cl->session, proto));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_compression_set_priority(cl->session, compress));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER));
//SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_set_default_priority(cl->session));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert)); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_protocol_set_priority(cl->session, proto));
if (!((cl->host_server->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT)) SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_compression_set_priority(cl->session, compress));
{
int kx[] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_kx_set_priority(cl->session, kx));
}
gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST); SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s));
//SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s));
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert));
if (!((cl->host_server->type & ECORE_CON_SSL) & ECORE_CON_LOAD_CERT))
{
int kx[] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_kx_set_priority(cl->session, kx));
}
gnutls_dh_set_prime_bits(cl->session, 2048); gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST);
gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
do gnutls_dh_set_prime_bits(cl->session, 2048);
{ gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
case ECORE_CON_SSL_STATE_HANDSHAKING:
ret = gnutls_handshake(cl->session); ret = gnutls_handshake(cl->session);
SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret));
} while (ret < 0);
if (!ret)
{
cl->handshaking = EINA_FALSE;
cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
}
default:
break;
}
/* TODO: add cert verification support */ /* TODO: add cert verification support */
return ECORE_CON_SSL_ERROR_NONE; return ECORE_CON_SSL_ERROR_NONE;
@ -875,31 +896,42 @@ error:
static Ecore_Con_Ssl_Error static Ecore_Con_Ssl_Error
_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr) _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
{ {
int ret = -1; int err, ret = -1;
SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx))); switch (svr->ssl_state)
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
SSL_set_connect_state(svr->ssl);
do
{ {
int err; case ECORE_CON_SSL_STATE_DONE:
return ECORE_CON_SSL_ERROR_NONE;
case ECORE_CON_SSL_STATE_INIT:
SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx)));
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd));
SSL_set_connect_state(svr->ssl);
svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
case ECORE_CON_SSL_STATE_HANDSHAKING:
ret = SSL_do_handshake(svr->ssl); ret = SSL_do_handshake(svr->ssl);
err = SSL_get_error(svr->ssl, ret); err = SSL_get_error(svr->ssl, ret);
SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL)); SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL));
} while (ret < 1);
if (ret == 1)
{
svr->handshaking = EINA_FALSE;
svr->ssl_state = ECORE_CON_SSL_STATE_DONE;
}
default:
break;
}
return ECORE_CON_SSL_ERROR_NONE; return ECORE_CON_SSL_ERROR_NONE;
error: error:
do do
{ {
unsigned long err; unsigned long sslerr;
err = ERR_get_error(); sslerr = ERR_get_error();
if (!err) break; if (!sslerr) break;
ERR("openssl error: %s", ERR_reason_error_string(err)); ERR("openssl error: %s", ERR_reason_error_string(sslerr));
} while (1); } while (1);
_ecore_con_ssl_server_shutdown_openssl(svr); _ecore_con_ssl_server_shutdown_openssl(svr);
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
@ -1078,30 +1110,40 @@ _ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf,
static Ecore_Con_Ssl_Error static Ecore_Con_Ssl_Error
_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl) _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
{ {
int ret = -1; int err, ret = -1;
SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx))); switch (cl->ssl_state)
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
SSL_set_accept_state(cl->ssl);
do
{ {
int err; case ECORE_CON_SSL_STATE_DONE:
return ECORE_CON_SSL_ERROR_NONE;
case ECORE_CON_SSL_STATE_INIT:
SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx)));
SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd));
SSL_set_accept_state(cl->ssl);
cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING;
case ECORE_CON_SSL_STATE_HANDSHAKING:
ret = SSL_do_handshake(cl->ssl); ret = SSL_do_handshake(cl->ssl);
err = SSL_get_error(cl->ssl, ret); err = SSL_get_error(cl->ssl, ret);
SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL)); SSL_ERROR_CHECK_GOTO_ERROR((err == SSL_ERROR_SYSCALL) || (err == SSL_ERROR_SSL));
} while (ret < 1); if (ret == 1)
{
cl->handshaking = EINA_FALSE;
cl->ssl_state = ECORE_CON_SSL_STATE_DONE;
}
default:
break;
}
return ECORE_CON_SSL_ERROR_NONE; return ECORE_CON_SSL_ERROR_NONE;
error: error:
do do
{ {
unsigned long err; unsigned long sslerr;
err = ERR_get_error(); sslerr = ERR_get_error();
if (!err) break; if (!sslerr) break;
ERR("openssl error: %s", ERR_reason_error_string(err)); ERR("openssl error: %s", ERR_reason_error_string(sslerr));
} while (1); } while (1);
_ecore_con_ssl_client_shutdown_openssl(cl); _ecore_con_ssl_client_shutdown_openssl(cl);
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;