Commit 82f3aa49 authored by Youness Alaoui's avatar Youness Alaoui Committed by Olivier Crête

Add support for MS Office Communicator pseudossl compatibility

parent 8fe85705
...@@ -1818,7 +1818,12 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent, ...@@ -1818,7 +1818,12 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent,
if (turn->type == NICE_RELAY_TYPE_TURN_TLS && if (turn->type == NICE_RELAY_TYPE_TURN_TLS &&
agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
nicesock = nice_pseudossl_socket_new (nicesock); nicesock = nice_pseudossl_socket_new (nicesock,
NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE);
} else if (agent->compatibility == NICE_COMPATIBILITY_OC2007 ||
agent->compatibility == NICE_COMPATIBILITY_OC2007R2) {
nicesock = nice_pseudossl_socket_new (nicesock,
NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC);
} }
cdisco->nicesock = nice_tcp_turn_socket_new (nicesock, cdisco->nicesock = nice_tcp_turn_socket_new (nicesock,
agent_to_turn_socket_compatibility (agent)); agent_to_turn_socket_compatibility (agent));
......
...@@ -55,6 +55,7 @@ typedef struct { ...@@ -55,6 +55,7 @@ typedef struct {
gboolean handshaken; gboolean handshaken;
NiceSocket *base_socket; NiceSocket *base_socket;
GQueue send_queue; GQueue send_queue;
NicePseudoSSLSocketCompatibility compatibility;
} PseudoSSLPriv; } PseudoSSLPriv;
...@@ -65,7 +66,7 @@ struct to_be_sent { ...@@ -65,7 +66,7 @@ struct to_be_sent {
}; };
static const gchar SSL_SERVER_HANDSHAKE[] = { static const gchar SSL_SERVER_GOOGLE_HANDSHAKE[] = {
0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00,
0x46, 0x03, 0x01, 0x42, 0x85, 0x45, 0xa7, 0x27, 0x46, 0x03, 0x01, 0x42, 0x85, 0x45, 0xa7, 0x27,
0xa9, 0x5d, 0xa0, 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0xa9, 0x5d, 0xa0, 0xb3, 0xc5, 0xe7, 0x53, 0xda,
...@@ -77,7 +78,7 @@ static const gchar SSL_SERVER_HANDSHAKE[] = { ...@@ -77,7 +78,7 @@ static const gchar SSL_SERVER_HANDSHAKE[] = {
0x30, 0x32, 0x6e, 0x38, 0x4d, 0xa2, 0x75, 0x57, 0x30, 0x32, 0x6e, 0x38, 0x4d, 0xa2, 0x75, 0x57,
0x41, 0x6c, 0x34, 0x5c, 0x00, 0x04, 0x00}; 0x41, 0x6c, 0x34, 0x5c, 0x00, 0x04, 0x00};
static const gchar SSL_CLIENT_HANDSHAKE[] = { static const gchar SSL_CLIENT_GOOGLE_HANDSHAKE[] = {
0x80, 0x46, 0x01, 0x03, 0x01, 0x00, 0x2d, 0x00, 0x80, 0x46, 0x01, 0x03, 0x01, 0x00, 0x2d, 0x00,
0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00,
0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02,
...@@ -88,6 +89,27 @@ static const gchar SSL_CLIENT_HANDSHAKE[] = { ...@@ -88,6 +89,27 @@ static const gchar SSL_CLIENT_HANDSHAKE[] = {
0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc,
0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea}; 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea};
static const gchar SSL_SERVER_MSOC_HANDSHAKE[] = {
0x16, 0x03, 0x01, 0x00, 0x4e, 0x02, 0x00, 0x00,
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0e,
0x00, 0x00, 0x00};
static const gchar SSL_CLIENT_MSOC_HANDSHAKE[] = {
0x16, 0x03, 0x01, 0x00, 0x2d, 0x01, 0x00, 0x00,
0x29, 0x03, 0x01, 0xc1, 0xfc, 0xd5, 0xa3, 0x6d,
0x93, 0xdd, 0x7e, 0x0b, 0x45, 0x67, 0x3f, 0xec,
0x79, 0x85, 0xfb, 0xbc, 0x3f, 0xd6, 0x60, 0xc2,
0xce, 0x84, 0x85, 0x08, 0x1b, 0x81, 0x21, 0xbc,
0xaa, 0x10, 0xfb, 0x00, 0x00, 0x02, 0x00, 0x18,
0x01, 0x00};
static void socket_close (NiceSocket *sock); static void socket_close (NiceSocket *sock);
static gint socket_recv_messages (NiceSocket *sock, static gint socket_recv_messages (NiceSocket *sock,
...@@ -104,14 +126,30 @@ static void free_to_be_sent (struct to_be_sent *tbs); ...@@ -104,14 +126,30 @@ static void free_to_be_sent (struct to_be_sent *tbs);
NiceSocket * NiceSocket *
nice_pseudossl_socket_new (NiceSocket *base_socket) nice_pseudossl_socket_new (NiceSocket *base_socket,
NicePseudoSSLSocketCompatibility compatibility)
{ {
PseudoSSLPriv *priv; PseudoSSLPriv *priv;
NiceSocket *sock = g_slice_new0 (NiceSocket); NiceSocket *sock;
const gchar *buf;
guint len;
if (compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) {
buf = SSL_CLIENT_MSOC_HANDSHAKE;
len = sizeof(SSL_CLIENT_MSOC_HANDSHAKE);
} else if (compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE) {
buf = SSL_CLIENT_GOOGLE_HANDSHAKE;
len = sizeof(SSL_CLIENT_GOOGLE_HANDSHAKE);
} else {
return NULL;
}
sock = g_slice_new0 (NiceSocket);
sock->priv = priv = g_slice_new0 (PseudoSSLPriv); sock->priv = priv = g_slice_new0 (PseudoSSLPriv);
priv->handshaken = FALSE; priv->handshaken = FALSE;
priv->base_socket = base_socket; priv->base_socket = base_socket;
priv->compatibility = compatibility;
sock->type = NICE_SOCKET_TYPE_PSEUDOSSL; sock->type = NICE_SOCKET_TYPE_PSEUDOSSL;
sock->fileno = priv->base_socket->fileno; sock->fileno = priv->base_socket->fileno;
...@@ -124,8 +162,7 @@ nice_pseudossl_socket_new (NiceSocket *base_socket) ...@@ -124,8 +162,7 @@ nice_pseudossl_socket_new (NiceSocket *base_socket)
/* We send 'to' NULL because it will always be to an already connected /* We send 'to' NULL because it will always be to an already connected
* TCP base socket, which ignores the destination */ * TCP base socket, which ignores the destination */
nice_socket_send_reliable (priv->base_socket, NULL, nice_socket_send_reliable (priv->base_socket, NULL, len, buf);
sizeof(SSL_CLIENT_HANDSHAKE), SSL_CLIENT_HANDSHAKE);
return sock; return sock;
} }
...@@ -145,6 +182,27 @@ socket_close (NiceSocket *sock) ...@@ -145,6 +182,27 @@ socket_close (NiceSocket *sock)
g_slice_free(PseudoSSLPriv, sock->priv); g_slice_free(PseudoSSLPriv, sock->priv);
} }
static gboolean
server_handshake_valid(NiceSocket *sock, GInputVector *data)
{
PseudoSSLPriv *priv = sock->priv;
if (priv->compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) {
if (data->size == sizeof(SSL_SERVER_MSOC_HANDSHAKE)) {
guint8 *buf = data->buffer;
memset(buf + 11, 0, 32);
memset(buf + 44, 0, 32);
return memcmp(SSL_SERVER_MSOC_HANDSHAKE, data->buffer,
sizeof(SSL_SERVER_MSOC_HANDSHAKE)) == 0;
}
return FALSE;
} else {
return data->size == sizeof(SSL_SERVER_GOOGLE_HANDSHAKE) &&
memcmp(SSL_SERVER_GOOGLE_HANDSHAKE, data->buffer,
sizeof(SSL_SERVER_GOOGLE_HANDSHAKE)) == 0;
}
}
static gint static gint
socket_recv_messages (NiceSocket *sock, socket_recv_messages (NiceSocket *sock,
...@@ -160,11 +218,18 @@ socket_recv_messages (NiceSocket *sock, ...@@ -160,11 +218,18 @@ socket_recv_messages (NiceSocket *sock,
recv_messages, n_recv_messages); recv_messages, n_recv_messages);
} }
} else { } else {
guint8 data[sizeof(SSL_SERVER_HANDSHAKE)]; guint8 data[MAX(sizeof(SSL_SERVER_GOOGLE_HANDSHAKE),
sizeof(SSL_SERVER_MSOC_HANDSHAKE))];
gint ret = -1; gint ret = -1;
GInputVector local_recv_buf = { data, sizeof (data) }; GInputVector local_recv_buf = { data, sizeof(data) };
NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 };
if (priv->compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) {
local_recv_buf.size = sizeof(SSL_SERVER_MSOC_HANDSHAKE);
} else {
local_recv_buf.size = sizeof(SSL_SERVER_GOOGLE_HANDSHAKE);
}
if (priv->base_socket) { if (priv->base_socket) {
ret = nice_socket_recv_messages (priv->base_socket, ret = nice_socket_recv_messages (priv->base_socket,
&local_recv_message, 1); &local_recv_message, 1);
...@@ -172,9 +237,7 @@ socket_recv_messages (NiceSocket *sock, ...@@ -172,9 +237,7 @@ socket_recv_messages (NiceSocket *sock,
if (ret <= 0) { if (ret <= 0) {
return ret; return ret;
} else if (ret == 1 && } else if (ret == 1 && server_handshake_valid(sock, &local_recv_buf)) {
local_recv_buf.size == sizeof (SSL_SERVER_HANDSHAKE) &&
memcmp(SSL_SERVER_HANDSHAKE, data, sizeof(SSL_SERVER_HANDSHAKE)) == 0) {
struct to_be_sent *tbs = NULL; struct to_be_sent *tbs = NULL;
priv->handshaken = TRUE; priv->handshaken = TRUE;
while ((tbs = g_queue_pop_head (&priv->send_queue))) { while ((tbs = g_queue_pop_head (&priv->send_queue))) {
......
...@@ -41,9 +41,24 @@ ...@@ -41,9 +41,24 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/**
* PseudosslCompatibility:
* @NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE: Use google compatible pseudossl
* @NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC: Use compatibility for Microsoft
* Office Communicator and Lync servers
*
* An enum to specify which pseudo SSL compatibility mode the #NiceSocket should
* use.
*/
typedef enum
{
NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE = 0,
NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC,
} NicePseudoSSLSocketCompatibility;
NiceSocket * NiceSocket *
nice_pseudossl_socket_new (NiceSocket *base_socket); nice_pseudossl_socket_new (NiceSocket *base_socket,
NicePseudoSSLSocketCompatibility compatibility);
G_END_DECLS G_END_DECLS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment