hijack gcrypt init call to fix threadsafe race in dingaling and fix buffer overrun in iksemel
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12575 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
2e2eea3b35
commit
0d38a7cf39
|
@ -27,7 +27,7 @@
|
|||
<!-- <load module="mod_ldap"/> -->
|
||||
|
||||
<!-- Endpoints -->
|
||||
<!-- <load module="mod_dingaling"/> -->
|
||||
<load module="mod_dingaling"/>
|
||||
<!-- <load module="mod_iax"/> -->
|
||||
<!-- <load module="mod_portaudio"/> -->
|
||||
<!-- <load module="mod_alsa"/> -->
|
||||
|
|
|
@ -108,6 +108,7 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
|
|||
fd_set fds;
|
||||
struct timeval tv, *tvptr;
|
||||
int len;
|
||||
char *bound;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
@ -115,20 +116,22 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
|
|||
FD_ZERO (&fds);
|
||||
FD_SET (sock, &fds);
|
||||
tv.tv_sec = timeout;
|
||||
|
||||
if (timeout != -1) tvptr = &tv; else tvptr = NULL;
|
||||
if (select (sock + 1, &fds, NULL, NULL, tvptr) > 0) {
|
||||
len = recv (sock, buffer, buf_len, 0);
|
||||
if (len > 0) {
|
||||
char *p, *e = NULL, *t = NULL;
|
||||
*(buffer+buf_len+1) = '\0';
|
||||
for (p = buffer; p && *p; p++) {
|
||||
bound = buffer + (len -1);
|
||||
|
||||
for (p = buffer; p < bound; p++) {
|
||||
if (*p == '>') {
|
||||
e = p;
|
||||
t = p+1;
|
||||
if (*t == '<') {
|
||||
continue;
|
||||
}
|
||||
while(t && *t) {
|
||||
while(p < bound && t < bound) {
|
||||
if (*t != ' ' && *t != '<') {
|
||||
t = e = NULL;
|
||||
break;
|
||||
|
|
|
@ -45,17 +45,15 @@ struct stream_data {
|
|||
};
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
static pthread_mutex_t tls_send_mutex;
|
||||
static pthread_mutex_t tls_recv_mutex;
|
||||
#include <gcrypt.h>
|
||||
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||
|
||||
static size_t
|
||||
tls_push (iksparser *prs, const char *buffer, size_t len)
|
||||
{
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
int ret;
|
||||
pthread_mutex_lock(&tls_send_mutex);
|
||||
ret = data->trans->send (data->sock, buffer, len);
|
||||
pthread_mutex_unlock(&tls_send_mutex);
|
||||
if (ret) return (size_t) -1;
|
||||
return len;
|
||||
}
|
||||
|
@ -65,9 +63,7 @@ tls_pull (iksparser *prs, char *buffer, size_t len)
|
|||
{
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
int ret;
|
||||
pthread_mutex_lock(&tls_recv_mutex);
|
||||
ret = data->trans->recv (data->sock, buffer, len, -1);
|
||||
pthread_mutex_unlock(&tls_recv_mutex);
|
||||
if (ret == -1) return (size_t) -1;
|
||||
return ret;
|
||||
}
|
||||
|
@ -82,6 +78,8 @@ handshake (struct stream_data *data)
|
|||
const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
|
||||
int ret;
|
||||
|
||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||
|
||||
if (gnutls_global_init () != 0)
|
||||
return IKS_NOMEM;
|
||||
|
||||
|
@ -99,8 +97,10 @@ handshake (struct stream_data *data)
|
|||
gnutls_mac_set_priority(data->sess, mac_priority);
|
||||
gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred);
|
||||
|
||||
|
||||
gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push);
|
||||
gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
|
||||
|
||||
gnutls_transport_set_ptr (data->sess, data->prs);
|
||||
|
||||
ret = gnutls_handshake (data->sess);
|
||||
|
@ -487,9 +487,15 @@ iks_connect_fd (iksparser *prs, int fd)
|
|||
int
|
||||
iks_fd (iksparser *prs)
|
||||
{
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
struct stream_data *data;
|
||||
|
||||
return (int) data->sock;
|
||||
if (prs) {
|
||||
data = iks_user_data (prs);
|
||||
if (data) {
|
||||
return (int) data->sock;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -603,24 +609,11 @@ int
|
|||
iks_init(void)
|
||||
{
|
||||
int ok = 0;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
if (pthread_mutexattr_init(&attr))
|
||||
return -1;
|
||||
|
||||
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
|
||||
ok = -1;
|
||||
|
||||
if (ok == 0 && pthread_mutex_init(&tls_send_mutex, &attr))
|
||||
ok = -1;
|
||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||
|
||||
if (ok == 0 && pthread_mutex_init(&tls_recv_mutex, &attr)) {
|
||||
pthread_mutex_destroy(&tls_send_mutex);
|
||||
ok = -1;
|
||||
}
|
||||
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
if (gnutls_global_init () != 0)
|
||||
return IKS_NOMEM;
|
||||
|
||||
return ok;
|
||||
|
||||
|
|
|
@ -1566,8 +1566,7 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
|||
}
|
||||
|
||||
fail:
|
||||
iks_disconnect(handle->parser);
|
||||
iks_parser_delete(handle->parser);
|
||||
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED);
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
|
||||
handle->state = CS_NEW;
|
||||
|
@ -1575,6 +1574,9 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
|||
while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) {
|
||||
microsleep(100);
|
||||
}
|
||||
|
||||
iks_disconnect(handle->parser);
|
||||
iks_parser_delete(handle->parser);
|
||||
}
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
||||
if (!ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
||||
|
|
Loading…
Reference in New Issue