[Asterisk-code-review] res_rtp_asterisk: Check remote ICE reset and reset local ice attrb (asterisk[16])

Salah Ahmed asteriskteam at digium.com
Wed Jan 27 14:19:13 CST 2021


Salah Ahmed has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/15385 )


Change subject: res_rtp_asterisk:  Check remote ICE reset and reset local ice attrb
......................................................................

res_rtp_asterisk:  Check remote ICE reset and reset local ice attrb

This change will check is the remote ICE session got reset or not by
checking the offered ufrag and password with session. If the remote ICE
reset session then Asterisk reset its local ufrag and password to reject
binding request with Old ufrag and Password.

ASTERISK-29266

Change-Id: I9c55e79a7af98a8fbb497d336b828ba41bc34eeb
---
M include/asterisk/rtp_engine.h
M main/rtp_engine.c
M res/res_pjsip_sdp_rtp.c
M res/res_rtp_asterisk.c
4 files changed, 92 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/85/15385/1

diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index 0584f2c..384810f 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -507,6 +507,10 @@
 		const char *username, const char *password);
 	/*! Callback to alter the number of ICE components on a session */
 	void (*change_components)(struct ast_rtp_instance *instance, int num_components);
+	/*! Callback to check the remote ice restarted */
+	int (*check_remote_ice_restart)(struct ast_rtp_instance *instance, const char *remote_ufrag, const char *remote_pass);
+	/*! Callback to alter the local username password*/
+	void (*reset_ice_ufrag_password)(struct ast_rtp_instance *instance);
 };
 
 /*! \brief DTLS setup types */
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index f88b877..5f87f64 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -2874,6 +2874,23 @@
 	ao2_unlock(instance);
 }
 
+static int rtp_ice_wrap_check_remote_ice_restart(struct ast_rtp_instance *instance,
+						 const char *username, const char *password)
+{
+	int remote_ice_reset = 0;
+	ao2_lock(instance);
+	remote_ice_reset = instance->engine->ice->check_remote_ice_restart(instance, username, password;
+	ao2_unlock(instance);
+	return remote_ice_reset;
+}
+
+static void rtp_ice_wrap_reset_ice_ufrag_password(struct ast_rtp_instance *instance)
+{
+	ao2_lock(instance);
+	instance->engine->ice->reset_ice_ufrag_password(instance);
+	ao2_unlock(instance);
+}
+
 static struct ast_rtp_engine_ice rtp_ice_wrappers = {
 	.set_authentication = rtp_ice_wrap_set_authentication,
 	.add_remote_candidate = rtp_ice_wrap_add_remote_candidate,
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 052f904..7896f6b 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -67,6 +67,8 @@
 static const char STR_AUDIO[] = "audio";
 static const char STR_VIDEO[] = "video";
 
+static void check_remote_ice_reset(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
+
 static int send_keepalive(const void *data)
 {
 	struct ast_sip_session_media *session_media = (struct ast_sip_session_media *) data;
@@ -1438,6 +1440,11 @@
 	/* If ICE support is enabled find all the needed attributes */
 	check_ice_support(session, session_media, stream);
 
+	/* If ICE support is enabled then check remote ICE started? */
+	if (session_media->remote_ice) {
+		check_remote_ice_reset(session, session_media, sdp, stream);
+	}
+
 	if (ast_sip_session_is_pending_stream_default(session, asterisk_stream) && media_type == AST_MEDIA_TYPE_AUDIO) {
 		/* Check if incomming SDP is changing the remotely held state */
 		if (ast_sockaddr_isnull(addrs) ||
@@ -1584,6 +1591,45 @@
 	return 0;
 }
 
+static void check_remote_ice_reset(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+				   const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
+{
+	struct ast_rtp_engine_ice *ice;
+	const pjmedia_sdp_attr *attr;
+	char remote_ufrag[256];
+	char remote_pwd[256];
+
+	/* If ICE support is not enabled or available exit early */
+	if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
+	  return;
+	}
+
+	attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
+	if (!attr) {
+		attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
+	}
+	if (attr) {
+		ast_copy_pj_str(remote_ufrag, (pj_str_t*)&attr->value, sizeof(remote_ufrag));
+	} else {
+		return;
+	}
+
+	attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
+	if (!attr) {
+		attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
+	}
+	if (attr) {
+		ast_copy_pj_str(remote_pwd, (pj_str_t*)&attr->value, sizeof(remote_pwd));
+	} else {
+		return;
+	}
+
+	int remote_ice_restarted = ice->check_remote_ice_restart(session_media->rtp, remote_ufrag, remote_pwd);
+	if (remote_ice_restarted) {
+		ice->reset_ice_ufrag_password(session_media->rtp);
+	}
+}
+
 /*! \brief Function which creates an outgoing stream */
 static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
 				      struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index dfec8f5..171d42d 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -271,6 +271,8 @@
 /*! \brief List of ICE host candidate mappings */
 static AST_RWLIST_HEAD_STATIC(host_candidates, ast_ice_host_candidate);
 
+static char *generate_random_string(char *buf, size_t size);
+
 #endif
 
 #define FLAG_3389_WARNING               (1 << 0)
@@ -774,6 +776,27 @@
 	}
 }
 
+static int ast_rtp_check_remote_ice_restart(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
+{
+	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+
+	if (!ast_strlen_zero(ufrag) && !ast_strlen_zero(password)) {
+		if ( strcmp(ufrag, rtp->remote_ufrag) ||
+		     strcmp(password, rtp->remote_passwd)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static void ast_rtp_reset_ice_ufrag_password(struct ast_rtp_instance *instance)
+{
+	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+
+	generate_random_string(rtp->local_ufrag, sizeof(rtp->local_ufrag));
+	generate_random_string(rtp->local_passwd, sizeof(rtp->local_passwd));
+}
+
 static int ice_candidate_cmp(void *obj, void *arg, int flags)
 {
 	struct ast_rtp_engine_ice_candidate *candidate1 = obj, *candidate2 = arg;
@@ -1730,6 +1753,8 @@
 	.set_role = ast_rtp_ice_set_role,
 	.turn_request = ast_rtp_ice_turn_request,
 	.change_components = ast_rtp_ice_change_components,
+	.check_remote_ice_restart = ast_rtp_check_remote_ice_restart,
+	.reset_ice_ufrag_password = ast_rtp_reset_ice_ufrag_password,
 };
 #endif
 

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15385
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-Change-Id: I9c55e79a7af98a8fbb497d336b828ba41bc34eeb
Gerrit-Change-Number: 15385
Gerrit-PatchSet: 1
Gerrit-Owner: Salah Ahmed <txrubel at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210127/da65863e/attachment-0001.html>


More information about the asterisk-code-review mailing list