Commit 8e5809b7 authored by Fabrice Bellet's avatar Fabrice Bellet Committed by Olivier Crête

discovery: fix an use-after-free in SFB user credentials

The base64 decoded username and password strings given to
stun_usage_turn_create() should not freed immediately, since they remain
used when handling the following related inbound stun replies.
parent 17170c9a
...@@ -141,6 +141,10 @@ typedef struct _TurnServer TurnServer; ...@@ -141,6 +141,10 @@ typedef struct _TurnServer TurnServer;
* @server: The #NiceAddress of the TURN server * @server: The #NiceAddress of the TURN server
* @username: The TURN username * @username: The TURN username
* @password: The TURN password * @password: The TURN password
* @decoded_username: The base64 decoded TURN username
* @decoded_password: The base64 decoded TURN password
* @decoded_username_len: The length of @decoded_username
* @decoded_password_len: The length of @decoded_password
* @type: The #NiceRelayType of the server * @type: The #NiceRelayType of the server
* *
* A structure to store the TURN relay settings * A structure to store the TURN relay settings
...@@ -152,6 +156,10 @@ struct _TurnServer ...@@ -152,6 +156,10 @@ struct _TurnServer
NiceAddress server; NiceAddress server;
gchar *username; gchar *username;
gchar *password; gchar *password;
uint8_t *decoded_username;
uint8_t *decoded_password;
gsize decoded_username_len;
gsize decoded_password_len;
NiceRelayType type; NiceRelayType type;
}; };
......
...@@ -1482,6 +1482,10 @@ turn_server_new (const gchar *server_ip, guint server_port, ...@@ -1482,6 +1482,10 @@ turn_server_new (const gchar *server_ip, guint server_port,
} }
turn->username = g_strdup (username); turn->username = g_strdup (username);
turn->password = g_strdup (password); turn->password = g_strdup (password);
turn->decoded_username =
g_base64_decode ((gchar *)username, &turn->decoded_username_len);
turn->decoded_password =
g_base64_decode ((gchar *)password, &turn->decoded_password_len);
turn->type = type; turn->type = type;
return turn; return turn;
...@@ -1503,6 +1507,8 @@ turn_server_unref (TurnServer *turn) ...@@ -1503,6 +1507,8 @@ turn_server_unref (TurnServer *turn)
if (turn->ref_count == 0) { if (turn->ref_count == 0) {
g_free (turn->username); g_free (turn->username);
g_free (turn->password); g_free (turn->password);
g_free (turn->decoded_username);
g_free (turn->decoded_password);
g_slice_free (TurnServer, turn); g_slice_free (TurnServer, turn);
} }
} }
......
...@@ -1551,8 +1551,10 @@ static void priv_turn_allocate_refresh_tick_unlocked (NiceAgent *agent, ...@@ -1551,8 +1551,10 @@ static void priv_turn_allocate_refresh_tick_unlocked (NiceAgent *agent,
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
username = g_base64_decode ((gchar *)username, &username_len); username = cand->candidate->turn->decoded_username;
password = g_base64_decode ((gchar *)password, &password_len); password = cand->candidate->turn->decoded_password;
username_len = cand->candidate->turn->decoded_username_len;
password_len = cand->candidate->turn->decoded_password_len;
} }
buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent, buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent,
...@@ -1562,12 +1564,6 @@ static void priv_turn_allocate_refresh_tick_unlocked (NiceAgent *agent, ...@@ -1562,12 +1564,6 @@ static void priv_turn_allocate_refresh_tick_unlocked (NiceAgent *agent,
password, password_len, password, password_len,
turn_compat); turn_compat);
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
g_free (username);
g_free (password);
}
nice_debug ("Agent %p : Sending allocate Refresh %zd", agent, nice_debug ("Agent %p : Sending allocate Refresh %zd", agent,
buffer_len); buffer_len);
......
...@@ -248,8 +248,10 @@ static gboolean refresh_remove_async (NiceAgent *agent, CandidateRefresh *cand, ...@@ -248,8 +248,10 @@ static gboolean refresh_remove_async (NiceAgent *agent, CandidateRefresh *cand,
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
username = g_base64_decode ((gchar *)username, &username_len); username = cand->candidate->turn->decoded_username;
password = g_base64_decode ((gchar *)password, &password_len); password = cand->candidate->turn->decoded_password;
username_len = cand->candidate->turn->decoded_username_len;
password_len = cand->candidate->turn->decoded_password_len;
} }
buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent, buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent,
...@@ -271,12 +273,6 @@ static gboolean refresh_remove_async (NiceAgent *agent, CandidateRefresh *cand, ...@@ -271,12 +273,6 @@ static gboolean refresh_remove_async (NiceAgent *agent, CandidateRefresh *cand,
(NiceTimeoutLockedCallback) on_refresh_remove_timeout, cand); (NiceTimeoutLockedCallback) on_refresh_remove_timeout, cand);
} }
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
g_free (username);
g_free (password);
}
cand->destroy_cb = cb; cand->destroy_cb = cb;
cand->destroy_cb_data = cb_data; cand->destroy_cb_data = cb_data;
...@@ -1155,8 +1151,10 @@ static gboolean priv_discovery_tick_unlocked (NiceAgent *agent) ...@@ -1155,8 +1151,10 @@ static gboolean priv_discovery_tick_unlocked (NiceAgent *agent)
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
username = g_base64_decode ((gchar *)username, &username_len); username = cand->turn->decoded_username;
password = g_base64_decode ((gchar *)password, &password_len); password = cand->turn->decoded_password;
username_len = cand->turn->decoded_username_len;
password_len = cand->turn->decoded_password_len;
} }
buffer_len = stun_usage_turn_create (&cand->stun_agent, buffer_len = stun_usage_turn_create (&cand->stun_agent,
...@@ -1167,12 +1165,6 @@ static gboolean priv_discovery_tick_unlocked (NiceAgent *agent) ...@@ -1167,12 +1165,6 @@ static gboolean priv_discovery_tick_unlocked (NiceAgent *agent)
username, username_len, username, username_len,
password, password_len, password, password_len,
turn_compat); turn_compat);
if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN ||
turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) {
g_free (username);
g_free (password);
}
} }
if (buffer_len > 0) { if (buffer_len > 0) {
......
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