forked from enlightenment/efl
+ecore_con_ssl_server_upgrade
+ecore_con_ssl_client_upgrade +ECORE_CON_EVENT_SERVER_UPGRADE +ECORE_CON_EVENT_CLIENT_UPGRADE new functions for upgrading an existing plaintext connection to SSL/TLS, as seen in STARTTLS and my nightmares SVN revision: 60359
This commit is contained in:
parent
a336a811ec
commit
64731e1dc9
|
@ -214,3 +214,9 @@
|
|||
2011-06-09 Cedric Bail
|
||||
|
||||
* Add ecore_pipe_wait (should only called from outside of the main loop).
|
||||
|
||||
2011-06-15 Mike Blumenkrantz
|
||||
|
||||
* Add ecore_con_ssl_client/server_upgrade to begin asynchronously upgrading an
|
||||
existing connection to SSL/TLS, emitting ECORE_CON_CLIENT/SERVER_UPGRADE event
|
||||
upon completion.
|
||||
|
|
|
@ -145,6 +145,12 @@ typedef struct _Ecore_Con_Url Ecore_Con_Url;
|
|||
*/
|
||||
typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Event_Client_Upgrade
|
||||
* Used as the @p data param for the corresponding event
|
||||
*/
|
||||
typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Event_Client_Del
|
||||
* Used as the @p data param for the corresponding event
|
||||
|
@ -163,6 +169,12 @@ typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error;
|
|||
*/
|
||||
typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Event_Server_Upgrade
|
||||
* Used as the @p data param for the corresponding event
|
||||
*/
|
||||
typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Event_Server_Del
|
||||
* Used as the @p data param for the corresponding event
|
||||
|
@ -214,6 +226,15 @@ struct _Ecore_Con_Event_Client_Add
|
|||
Ecore_Con_Client *client; /** the client that connected */
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Event_Client_Upgrade
|
||||
* Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event
|
||||
*/
|
||||
struct _Ecore_Con_Event_Client_Upgrade
|
||||
{
|
||||
Ecore_Con_Client *client; /** the client that completed handshake */
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Event_Client_Del
|
||||
* Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event
|
||||
|
@ -242,6 +263,15 @@ struct _Ecore_Con_Event_Server_Add
|
|||
Ecore_Con_Server *server; /** the server that was connected to */
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Event_Server_Upgrade
|
||||
* Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event
|
||||
*/
|
||||
struct _Ecore_Con_Event_Server_Upgrade
|
||||
{
|
||||
Ecore_Con_Server *server; /** the server that was connected to */
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Event_Server_Del
|
||||
* Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event
|
||||
|
@ -329,12 +359,16 @@ EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
|
|||
EAPI extern int ECORE_CON_EVENT_CLIENT_DEL;
|
||||
/** A client experienced an error */
|
||||
EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR;
|
||||
/** A client connection has been upgraded to SSL */
|
||||
EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE;
|
||||
/** A server was created */
|
||||
EAPI extern int ECORE_CON_EVENT_SERVER_ADD;
|
||||
/** A server connection was lost */
|
||||
EAPI extern int ECORE_CON_EVENT_SERVER_DEL;
|
||||
/** A server experienced an error */
|
||||
EAPI extern int ECORE_CON_EVENT_SERVER_ERROR;
|
||||
/** A server connection has been upgraded to SSL */
|
||||
EAPI extern int ECORE_CON_EVENT_SERVER_UPGRADE;
|
||||
/** A client connected to the server has sent data */
|
||||
EAPI extern int ECORE_CON_EVENT_CLIENT_DATA;
|
||||
/** A server connection object has data */
|
||||
|
@ -427,6 +461,8 @@ EAPI Eina_Bool ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, c
|
|||
EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const char *crl_file);
|
||||
EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file);
|
||||
EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr);
|
||||
EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type);
|
||||
EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -1178,13 +1178,15 @@ ecore_con_event_server_add(Ecore_Con_Server *svr)
|
|||
{
|
||||
/* we got our server! */
|
||||
Ecore_Con_Event_Server_Add *e;
|
||||
int ev = ECORE_CON_EVENT_SERVER_ADD;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
|
||||
EINA_SAFETY_ON_NULL_RETURN(e);
|
||||
|
||||
svr->event_count++;
|
||||
e->server = svr;
|
||||
ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
|
||||
if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE;
|
||||
ecore_event_add(ev, e,
|
||||
_ecore_con_event_server_add_free, NULL);
|
||||
}
|
||||
|
||||
|
@ -1234,6 +1236,7 @@ void
|
|||
ecore_con_event_client_add(Ecore_Con_Client *cl)
|
||||
{
|
||||
Ecore_Con_Event_Client_Add *e;
|
||||
int ev = ECORE_CON_EVENT_CLIENT_ADD;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
|
||||
EINA_SAFETY_ON_NULL_RETURN(e);
|
||||
|
@ -1242,7 +1245,8 @@ ecore_con_event_client_add(Ecore_Con_Client *cl)
|
|||
cl->host_server->event_count++;
|
||||
_ecore_con_cl_timer_update(cl);
|
||||
e->client = cl;
|
||||
ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
|
||||
if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE;
|
||||
ecore_event_add(ev, e,
|
||||
(Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server);
|
||||
|
||||
}
|
||||
|
@ -2018,7 +2022,7 @@ _ecore_con_svr_tcp_handler(void *data,
|
|||
|
||||
ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
|
||||
|
||||
if (svr->type & ECORE_CON_SSL)
|
||||
if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL))
|
||||
{
|
||||
cl->handshaking = EINA_TRUE;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
|
||||
|
@ -2284,7 +2288,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl)
|
|||
_ecore_con_cl_timer_update(cl);
|
||||
}
|
||||
|
||||
if (!(cl->host_server->type & ECORE_CON_SSL))
|
||||
if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade))
|
||||
{
|
||||
num = read(cl->fd, buf, sizeof(buf));
|
||||
/* 0 is not a valid return value for a tcp socket */
|
||||
|
@ -2445,7 +2449,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl)
|
|||
{
|
||||
num = cl->buf_size - cl->buf_offset;
|
||||
if (num <= 0) return;
|
||||
if (!(cl->host_server->type & ECORE_CON_SSL))
|
||||
if (!(cl->host_server->type & ECORE_CON_SSL) || (!cl->upgrade))
|
||||
count = write(cl->fd, cl->buf + cl->buf_offset, num);
|
||||
else
|
||||
count = ecore_con_ssl_client_write(cl, cl->buf + cl->buf_offset, num);
|
||||
|
|
|
@ -314,7 +314,7 @@ void
|
|||
ecore_con_info_data_clear(void *info)
|
||||
{
|
||||
Ecore_Con_CAres *cares = info;
|
||||
cares->data = NULL;
|
||||
if (cares) cares->data = NULL;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
|
|
@ -106,8 +106,9 @@ struct _Ecore_Con_Client
|
|||
SSL *ssl;
|
||||
int ssl_err;
|
||||
#endif
|
||||
Eina_Bool handshaking : 1;
|
||||
Ecore_Con_Ssl_State ssl_state;
|
||||
Eina_Bool handshaking : 1;
|
||||
Eina_Bool upgrade : 1;
|
||||
Eina_Bool dead : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
@ -152,6 +153,8 @@ struct _Ecore_Con_Server
|
|||
Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
|
||||
Eina_Bool connecting : 1; /* EINA_FALSE if just initialized or connected */
|
||||
Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */
|
||||
Eina_Bool upgrade : 1;
|
||||
Eina_Bool ssl_prepared : 1;
|
||||
Eina_Bool use_cert : 1; /* EINA_TRUE if using certificate auth */
|
||||
Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */
|
||||
Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
|
||||
EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0;
|
||||
EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0;
|
||||
|
||||
static int _init_con_ssl_init_count = 0;
|
||||
|
||||
#ifdef USE_GNUTLS
|
||||
|
@ -157,29 +160,16 @@ static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con
|
|||
static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file);
|
||||
|
||||
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
|
||||
SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (Ecore_Con_Server *
|
||||
svr);
|
||||
static int
|
||||
SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server * svr,
|
||||
unsigned char *buf, int size);
|
||||
static int
|
||||
SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *
|
||||
svr,
|
||||
unsigned char *buf, int size);
|
||||
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 int SSL_SUFFIX(_ecore_con_ssl_server_read) (Ecore_Con_Server *svr, unsigned char *buf, int size);
|
||||
static int SSL_SUFFIX(_ecore_con_ssl_server_write) (Ecore_Con_Server *svr, unsigned char *buf, int size);
|
||||
|
||||
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,
|
||||
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,
|
||||
unsigned char *buf, int size);
|
||||
static int
|
||||
SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
|
||||
static int SSL_SUFFIX(_ecore_con_ssl_client_write) (Ecore_Con_Client * cl,
|
||||
unsigned char *buf, int size);
|
||||
|
||||
/*
|
||||
|
@ -190,7 +180,13 @@ Ecore_Con_Ssl_Error
|
|||
ecore_con_ssl_init(void)
|
||||
{
|
||||
if (!_init_con_ssl_init_count++)
|
||||
{
|
||||
SSL_SUFFIX(_ecore_con_ssl_init) ();
|
||||
#if _ECORE_CON_SSL_AVAILABLE != 0
|
||||
ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new();
|
||||
ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new();
|
||||
#endif
|
||||
}
|
||||
|
||||
return _init_con_ssl_init_count;
|
||||
}
|
||||
|
@ -409,6 +405,82 @@ ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr,
|
|||
return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Upgrade a connection to a specified level of encryption
|
||||
*
|
||||
* Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
|
||||
* Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted.
|
||||
* The connection should be treated as disconnected until the next event.
|
||||
* @param svr The server object
|
||||
* @param ssl_type The SSL connection type (ONLY).
|
||||
* @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
|
||||
* @note This function is NEVER to be used on a server object created with ecore_con_server_add
|
||||
* @warning Setting a wrong value for @p compl_type WILL mess up your program.
|
||||
* @since 1.1
|
||||
*/
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
#if _ECORE_CON_SSL_AVAILABLE == 0
|
||||
return EINA_FALSE;
|
||||
#endif
|
||||
|
||||
if (!svr->ssl_prepared)
|
||||
{
|
||||
if (ecore_con_ssl_server_prepare(svr, ssl_type))
|
||||
return EINA_FALSE;
|
||||
}
|
||||
svr->type |= ssl_type;
|
||||
svr->upgrade = EINA_TRUE;
|
||||
svr->handshaking = EINA_TRUE;
|
||||
svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
|
||||
return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Upgrade a connection to a specified level of encryption
|
||||
*
|
||||
* Use this function to begin an SSL handshake on a connection (STARTTLS or similar).
|
||||
* Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted.
|
||||
* The connection should be treated as disconnected until the next event.
|
||||
* @param cl The client object
|
||||
* @param compl_type The SSL connection type (ONLY).
|
||||
* @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
|
||||
* @warning Setting a wrong value for @p compl_type WILL mess up your program.
|
||||
* @since 1.1
|
||||
*/
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
#if _ECORE_CON_SSL_AVAILABLE == 0
|
||||
return EINA_FALSE;
|
||||
#endif
|
||||
|
||||
if (!cl->host_server->ssl_prepared)
|
||||
{
|
||||
if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type))
|
||||
return EINA_FALSE;
|
||||
}
|
||||
cl->host_server->type |= ssl_type;
|
||||
cl->upgrade = EINA_TRUE;
|
||||
cl->host_server->upgrade = EINA_TRUE;
|
||||
cl->handshaking = EINA_TRUE;
|
||||
cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
|
||||
return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -490,6 +562,7 @@ _ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr,
|
|||
SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c));
|
||||
}
|
||||
|
||||
svr->ssl_prepared = EINA_TRUE;
|
||||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
|
||||
error:
|
||||
|
@ -498,6 +571,7 @@ error:
|
|||
return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
|
||||
{
|
||||
|
@ -1538,6 +1612,12 @@ _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__,
|
|||
return ECORE_CON_SSL_ERROR_NONE;
|
||||
}
|
||||
|
||||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_server_upgrade_none(Ecore_Con_Server *svr __UNUSED__)
|
||||
{
|
||||
return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__)
|
||||
{
|
||||
|
@ -1594,6 +1674,12 @@ _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_client_upgrade_none(Ecore_Con_Client *cl __UNUSED__)
|
||||
{
|
||||
return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static Ecore_Con_Ssl_Error
|
||||
_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue