conn: send stream attribute "from" after TLS negotiation
RFC6120 states that client SHOULD send the "from" attribute in <stream>. Because of privacy concerns attribute "from" should be sent only after TLS negotiation. This step ensures that the server is verified by its certificate and protects JID from MITM attack. Fixes #163. Also should be helpful for #162.
This commit is contained in:
65
src/conn.c
65
src/conn.c
@@ -52,6 +52,9 @@ static int _disconnect_cleanup(xmpp_conn_t *conn, void *userdata);
|
|||||||
static char *_conn_build_stream_tag(xmpp_conn_t *conn,
|
static char *_conn_build_stream_tag(xmpp_conn_t *conn,
|
||||||
char **attributes,
|
char **attributes,
|
||||||
size_t attributes_len);
|
size_t attributes_len);
|
||||||
|
static int _conn_open_stream_with_attributes(xmpp_conn_t *conn,
|
||||||
|
char **attributes,
|
||||||
|
size_t attributes_len);
|
||||||
static void _conn_attributes_new(xmpp_conn_t *conn,
|
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||||
char **attrs,
|
char **attrs,
|
||||||
char ***attributes,
|
char ***attributes,
|
||||||
@@ -656,20 +659,12 @@ int xmpp_conn_open_stream(xmpp_conn_t *conn,
|
|||||||
char **attributes,
|
char **attributes,
|
||||||
size_t attributes_len)
|
size_t attributes_len)
|
||||||
{
|
{
|
||||||
char *tag;
|
|
||||||
|
|
||||||
if (!conn->is_raw)
|
if (!conn->is_raw)
|
||||||
return XMPP_EINVOP;
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
tag = _conn_build_stream_tag(conn, attributes, attributes_len);
|
|
||||||
if (!tag)
|
|
||||||
return XMPP_EMEM;
|
|
||||||
|
|
||||||
conn_prepare_reset(conn, auth_handle_open_raw);
|
conn_prepare_reset(conn, auth_handle_open_raw);
|
||||||
xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag);
|
|
||||||
xmpp_free(conn->ctx, tag);
|
|
||||||
|
|
||||||
return XMPP_EOK;
|
return _conn_open_stream_with_attributes(conn, attributes, attributes_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start synchronous TLS handshake with the server.
|
/** Start synchronous TLS handshake with the server.
|
||||||
@@ -884,17 +879,31 @@ void xmpp_send(xmpp_conn_t *conn, xmpp_stanza_t *stanza)
|
|||||||
*/
|
*/
|
||||||
void conn_open_stream(xmpp_conn_t *conn)
|
void conn_open_stream(xmpp_conn_t *conn)
|
||||||
{
|
{
|
||||||
xmpp_send_raw_string(conn,
|
size_t attributes_len;
|
||||||
"<?xml version=\"1.0\"?>"
|
int rc;
|
||||||
"<stream:stream to=\"%s\" "
|
char *from = NULL;
|
||||||
"xml:lang=\"%s\" "
|
char *ns = conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT;
|
||||||
"version=\"1.0\" "
|
char *attributes[12] = {
|
||||||
"xmlns=\"%s\" "
|
"to", conn->domain, "xml:lang", conn->lang,
|
||||||
"xmlns:stream=\"%s\">",
|
"version", "1.0", "xmlns", ns,
|
||||||
conn->domain, conn->lang,
|
"xmlns:stream", XMPP_NS_STREAMS, "from", NULL};
|
||||||
conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT
|
|
||||||
: XMPP_NS_COMPONENT,
|
attributes_len = ARRAY_SIZE(attributes);
|
||||||
XMPP_NS_STREAMS);
|
if (conn->tls && conn->jid && strchr(conn->jid, '@') != NULL)
|
||||||
|
from = xmpp_jid_bare(conn->ctx, conn->jid);
|
||||||
|
|
||||||
|
if (from)
|
||||||
|
attributes[attributes_len - 1] = from;
|
||||||
|
else
|
||||||
|
attributes_len -= 2;
|
||||||
|
|
||||||
|
rc = _conn_open_stream_with_attributes(conn, attributes, attributes_len);
|
||||||
|
if (rc != XMPP_EOK) {
|
||||||
|
xmpp_error(conn->ctx, "conn", "Cannot build stream tag: memory error");
|
||||||
|
conn_disconnect(conn);
|
||||||
|
}
|
||||||
|
if (from)
|
||||||
|
xmpp_free(conn->ctx, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
int conn_tls_start(xmpp_conn_t *conn)
|
int conn_tls_start(xmpp_conn_t *conn)
|
||||||
@@ -1113,6 +1122,22 @@ static char *_conn_build_stream_tag(xmpp_conn_t *conn,
|
|||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _conn_open_stream_with_attributes(xmpp_conn_t *conn,
|
||||||
|
char **attributes,
|
||||||
|
size_t attributes_len)
|
||||||
|
{
|
||||||
|
char *tag;
|
||||||
|
|
||||||
|
tag = _conn_build_stream_tag(conn, attributes, attributes_len);
|
||||||
|
if (!tag)
|
||||||
|
return XMPP_EMEM;
|
||||||
|
|
||||||
|
xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag);
|
||||||
|
xmpp_free(conn->ctx, tag);
|
||||||
|
|
||||||
|
return XMPP_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
static void _conn_attributes_new(xmpp_conn_t *conn,
|
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||||
char **attrs,
|
char **attrs,
|
||||||
char ***attributes,
|
char ***attributes,
|
||||||
|
|||||||
Reference in New Issue
Block a user