pjproject: sync patches with asterisk 18.5.1

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
This commit is contained in:
Sebastian Kemper 2021-07-31 11:24:10 +02:00
parent aa19540243
commit 54ad579b30
4 changed files with 442 additions and 1 deletions

View file

@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=pjproject
PKG_VERSION:=2.10
PKG_RELEASE:=3
PKG_RELEASE:=4
# download "vX.Y.tar.gz" as "pjproject-vX.Y.tar.gz"
PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz

View file

@ -0,0 +1,201 @@
From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
Date: Thu, 22 Apr 2021 14:03:28 +0800
Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408)
Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
---
pjsip/src/pjsip/sip_auth_client.c | 32 +++++--
tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++
.../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++
3 files changed, 117 insertions(+), 5 deletions(-)
create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py
create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool
pjsip_hdr *hdr;
pj_status_t status;
- /* See if we have sent authorization header for this realm */
+ /* See if we have sent authorization header for this realm (and scheme) */
hdr = tdata->msg->hdr.next;
while (hdr != &tdata->msg->hdr) {
if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&
@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool
{
sent_auth = (pjsip_authorization_hdr*) hdr;
if (pj_stricmp(&hchal->challenge.common.realm,
- &sent_auth->credential.common.realm )==0)
+ &sent_auth->credential.common.realm)==0 &&
+ pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0)
{
/* If this authorization has empty response, remove it. */
if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool
hdr = hdr->next;
pj_list_erase(sent_auth);
continue;
+ } else
+ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
+ pj_stricmp(&sent_auth->credential.digest.algorithm,
+ &hchal->challenge.digest.algorithm)!=0)
+ {
+ /* Same 'digest' scheme but different algo */
+ hdr = hdr->next;
+ continue;
} else {
/* Found previous authorization attempt */
break;
@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
{
pjsip_tx_data *tdata;
const pjsip_hdr *hdr;
- unsigned chal_cnt;
+ unsigned chal_cnt, auth_cnt;
pjsip_via_hdr *via;
pj_status_t status;
+ pj_status_t last_auth_err;
PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,
PJ_EINVAL);
@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
*/
hdr = rdata->msg_info.msg->hdr.next;
chal_cnt = 0;
+ auth_cnt = 0;
+ last_auth_err = PJSIP_EAUTHNOAUTH;
while (hdr != &rdata->msg_info.msg->hdr) {
pjsip_cached_auth *cached_auth;
const pjsip_www_authenticate_hdr *hchal;
@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
*/
status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
tdata, sess, cached_auth, &hauth);
- if (status != PJ_SUCCESS)
- return status;
+ if (status != PJ_SUCCESS) {
+ last_auth_err = status;
+
+ /* Process next header. */
+ hdr = hdr->next;
+ continue;
+ }
if (pj_pool_get_used_size(cached_auth->pool) >
PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini
/* Process next header. */
hdr = hdr->next;
+ auth_cnt++;
}
/* Check if challenge is present */
if (chal_cnt == 0)
return PJSIP_EAUTHNOCHAL;
+ /* Check if any authorization header has been created */
+ if (auth_cnt == 0)
+ return last_auth_err;
+
/* Remove branch param in Via header. */
via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
via->branch_param.slen = 0;
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
@@ -0,0 +1,7 @@
+# $Id$
+#
+import inc_const as const
+
+PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"]
+
+PJSUA_EXPECTS = [[0, "registration success", ""]]
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="Basic UAS responder">
+ <recv request="REGISTER" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 100 Trying
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 401 Unauthorized
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD2, qop="auth"
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <recv request="REGISTER" crlf="true">
+ <action>
+ <ereg regexp=".*"
+ search_in="hdr"
+ header="Authorization:"
+ assign_to="have_auth" />
+ </action>
+ </recv>
+
+ <nop next="resp_okay" test="have_auth" />
+
+ <send next="end">
+ <![CDATA[
+ SIP/2.0 403 no auth
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ [last_Contact:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <label id="resp_okay" />
+
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ [last_Contact:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <label id="end" />
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+

View file

@ -0,0 +1,78 @@
commit f0ff5817d0647bdecd1ec99488db9378e304cf83
Author: sauwming <ming@teluu.com>
Date: Mon May 17 09:56:27 2021 +0800
Fix double free of stun session (#2709)
--- a/pjnath/include/pjnath/stun_session.h
+++ b/pjnath/include/pjnath/stun_session.h
@@ -341,6 +341,7 @@ struct pj_stun_tx_data
pj_pool_t *pool; /**< Pool. */
pj_stun_session *sess; /**< The STUN session. */
pj_stun_msg *msg; /**< The STUN message. */
+ pj_bool_t is_destroying; /**< Is destroying? */
void *token; /**< The token. */
--- a/pjnath/src/pjnath/stun_session.c
+++ b/pjnath/src/pjnath/stun_session.c
@@ -167,16 +167,27 @@ static void tdata_on_destroy(void *arg)
{
pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg;
+ if (tdata->grp_lock) {
+ pj_grp_lock_dec_ref(tdata->sess->grp_lock);
+ }
+
pj_pool_safe_release(&tdata->pool);
}
static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
{
- TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata,
- force, tdata->client_tsx));
+ TRACE_((THIS_FILE,
+ "tdata %p destroy request, force=%d, tsx=%p, destroying=%d",
+ tdata, force, tdata->client_tsx, tdata->is_destroying));
+
+ /* Just return if destroy has been requested before */
+ if (tdata->is_destroying)
+ return;
/* STUN session may have been destroyed, except when tdata is cached. */
+ tdata->is_destroying = PJ_TRUE;
+
if (tdata->res_timer.id != PJ_FALSE) {
pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,
&tdata->res_timer, PJ_FALSE);
@@ -189,7 +200,6 @@ static void destroy_tdata(pj_stun_tx_dat
pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);
}
if (tdata->grp_lock) {
- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
pj_grp_lock_dec_ref(tdata->grp_lock);
} else {
tdata_on_destroy(tdata);
@@ -200,11 +210,11 @@ static void destroy_tdata(pj_stun_tx_dat
/* "Probably" this is to absorb retransmission */
pj_time_val delay = {0, 300};
pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);
+ tdata->is_destroying = PJ_FALSE;
} else {
pj_list_erase(tdata);
if (tdata->grp_lock) {
- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
pj_grp_lock_dec_ref(tdata->grp_lock);
} else {
tdata_on_destroy(tdata);
@@ -238,7 +248,7 @@ static void on_cache_timeout(pj_timer_he
sess = tdata->sess;
pj_grp_lock_acquire(sess->grp_lock);
- if (sess->is_destroying) {
+ if (sess->is_destroying || tdata->is_destroying) {
pj_grp_lock_release(sess->grp_lock);
return;
}

View file

@ -0,0 +1,162 @@
From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Wed, 16 Jun 2021 12:12:35 +0700
Subject: [PATCH 1/2] - Avoid SSL socket parent/listener getting destroyed
during handshake by increasing parent's reference count. - Add missing SSL
socket close when the newly accepted SSL socket is discarded in SIP TLS
transport.
---
pjlib/src/pj/ssl_sock_imp_common.c | 44 +++++++++++++++++++++--------
pjsip/src/pjsip/sip_transport_tls.c | 23 ++++++++++++++-
2 files changed, 55 insertions(+), 12 deletions(-)
--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
@@ -224,6 +224,8 @@ static pj_bool_t on_handshake_complete(p
/* Accepting */
if (ssock->is_server) {
+ pj_bool_t ret = PJ_TRUE;
+
if (status != PJ_SUCCESS) {
/* Handshake failed in accepting, destroy our self silently. */
@@ -241,6 +243,12 @@ static pj_bool_t on_handshake_complete(p
status);
}
+ /* Decrement ref count of parent */
+ if (ssock->parent->param.grp_lock) {
+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
+ ssock->parent = NULL;
+ }
+
/* Originally, this is a workaround for ticket #985. However,
* a race condition may occur in multiple worker threads
* environment when we are destroying SSL objects while other
@@ -284,23 +292,29 @@ static pj_bool_t on_handshake_complete(p
return PJ_FALSE;
}
+
/* Notify application the newly accepted SSL socket */
if (ssock->param.cb.on_accept_complete2) {
- pj_bool_t ret;
ret = (*ssock->param.cb.on_accept_complete2)
(ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr),
status);
- if (ret == PJ_FALSE)
- return PJ_FALSE;
} else if (ssock->param.cb.on_accept_complete) {
- pj_bool_t ret;
ret = (*ssock->param.cb.on_accept_complete)
(ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));
- if (ret == PJ_FALSE)
- return PJ_FALSE;
}
+
+ /* Decrement ref count of parent and reset parent (we don't need it
+ * anymore, right?).
+ */
+ if (ssock->parent->param.grp_lock) {
+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
+ ssock->parent = NULL;
+ }
+
+ if (ret == PJ_FALSE)
+ return PJ_FALSE;
}
/* Connecting */
@@ -864,9 +878,13 @@ static pj_bool_t asock_on_accept_complet
if (status != PJ_SUCCESS)
goto on_return;
+ /* Set parent and add ref count (avoid parent destroy during handshake) */
+ ssock->parent = ssock_parent;
+ if (ssock->parent->param.grp_lock)
+ pj_grp_lock_add_ref(ssock->parent->param.grp_lock);
+
/* Update new SSL socket attributes */
ssock->sock = newsock;
- ssock->parent = ssock_parent;
ssock->is_server = PJ_TRUE;
if (ssock_parent->cert) {
status = pj_ssl_sock_set_certificate(ssock, ssock->pool,
@@ -913,16 +931,20 @@ static pj_bool_t asock_on_accept_complet
ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool,
ssock->param.async_cnt,
sizeof(void*));
- if (!ssock->asock_rbuf)
- return PJ_ENOMEM;
+ if (!ssock->asock_rbuf) {
+ status = PJ_ENOMEM;
+ goto on_return;
+ }
for (i = 0; i<ssock->param.async_cnt; ++i) {
- ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
+ ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
ssock->pool,
ssock->param.read_buffer_size +
sizeof(read_data_t*));
- if (!ssock->asock_rbuf[i])
- return PJ_ENOMEM;
+ if (!ssock->asock_rbuf[i]) {
+ status = PJ_ENOMEM;
+ goto on_return;
+ }
}
/* Create active socket */
--- a/pjsip/src/pjsip/sip_transport_tls.c
+++ b/pjsip/src/pjsip/sip_transport_tls.c
@@ -1325,9 +1325,26 @@ static pj_bool_t on_accept_complete2(pj_
PJ_UNUSED_ARG(src_addr_len);
listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock);
+ if (!listener) {
+ /* Listener already destroyed, e.g: after TCP accept but before SSL
+ * handshake is completed.
+ */
+ if (new_ssock && accept_status == PJ_SUCCESS) {
+ /* Close the SSL socket if the accept op is successful */
+ PJ_LOG(4,(THIS_FILE,
+ "Incoming TLS connection from %s (sock=%d) is discarded "
+ "because listener is already destroyed",
+ pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),
+ new_ssock));
+
+ pj_ssl_sock_close(new_ssock);
+ }
+
+ return PJ_FALSE;
+ }
if (accept_status != PJ_SUCCESS) {
- if (listener && listener->tls_setting.on_accept_fail_cb) {
+ if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_ssl_sock_info ssi;
@@ -1350,6 +1367,8 @@ static pj_bool_t on_accept_complete2(pj_
PJ_ASSERT_RETURN(new_ssock, PJ_TRUE);
if (!listener->is_registered) {
+ pj_ssl_sock_close(new_ssock);
+
if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_bzero(&param, sizeof(param));
@@ -1401,6 +1420,8 @@ static pj_bool_t on_accept_complete2(pj_
ssl_info.grp_lock, &tls);
if (status != PJ_SUCCESS) {
+ pj_ssl_sock_close(new_ssock);
+
if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_bzero(&param, sizeof(param));