Merge pull request #700 from micmac1/ast16.20

[19.07] bump pjproject, asterisk & chan-lantiq
This commit is contained in:
micmac1 2021-11-07 20:54:39 +01:00 committed by GitHub
commit 1b0861c248
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 885 additions and 1469 deletions

View file

@ -10,14 +10,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=pjproject
PKG_VERSION:=2.8
PKG_RELEASE:=3
PKG_VERSION:=2.10
PKG_RELEASE:=1
PKG_SOURCE:=pjproject-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://www.pjsip.org/release/$(PKG_VERSION)
PKG_HASH:=503d0bd7f9f13dc1492ac9b71b761b1089851fbb608b9a13996edc3c42006f79
# download "vX.Y.tar.gz" as "pjproject-vX.Y.tar.gz"
PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_URL_FILE)
PKG_SOURCE_URL:=https://github.com/pjsip/$(PKG_NAME)/archive
PKG_HASH:=936a4c5b98601b52325463a397ddf11ab4106c6a7b04f8dc7cdd377efbb597de
PKG_INSTALL:=1
PKG_FIXUP:=autoreconf
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
@ -34,7 +35,7 @@ define Package/pjproject/Default
SECTION:=lib
CATEGORY:=Libraries
SUBMENU:=Telephony
URL:=http://www.pjsip.org
URL:=https://www.pjsip.org
DEPENDS:=$(CXX_DEPENDS) +libopenssl +libuuid +libpthread
endef
@ -60,6 +61,7 @@ endef
CONFIGURE_ARGS+= \
$(if $(CONFIG_SOFT_FLOAT),--disable-floating-point) \
--disable-bcg729 \
--disable-darwin-ssl \
--disable-ext-sound \
--disable-ffmpeg \
--disable-g711-codec \
@ -92,6 +94,7 @@ CONFIGURE_ARGS+= \
TARGET_CFLAGS+=$(TARGET_CPPFLAGS)
define Build/Compile
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) dep
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)
endef
@ -108,7 +111,8 @@ define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(SED) 's|$(TARGET_CFLAGS)||g' $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc $(1)/usr/lib/pkgconfig
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc \
$(1)/usr/lib/pkgconfig
endef
$(eval $(call PJSIPpackage,libpj,libpj,+librt))

View file

@ -58,13 +58,13 @@
+ Enabling it will result in SEGFAULTS when URIs containing escape sequences are encountered.
+*/
+#undef PJSIP_UNESCAPE_IN_PLACE
+#define PJSIP_MAX_PKT_LEN 32000
+#define PJSIP_MAX_PKT_LEN 65535
+
+#undef PJ_TODO
+#define PJ_TODO(x)
+
+/* Defaults too low for WebRTC */
+#define PJ_ICE_MAX_CAND 32
+#define PJ_ICE_MAX_CAND 64
+#define PJ_ICE_MAX_CHECKS (PJ_ICE_MAX_CAND * PJ_ICE_MAX_CAND)
+
+/* Increase limits to allow more formats */

View file

@ -1,6 +1,6 @@
--- a/build.mak.in
+++ b/build.mak.in
@@ -292,7 +292,6 @@ export APP_LDLIBS := $(PJSUA_LIB_LDLIB)
@@ -296,7 +296,6 @@ export APP_LDLIBS := $(PJSUA_LIB_LDLIB)
$(PJLIB_LDLIB) \
@LIBS@
export APP_LDXXLIBS := $(PJSUA2_LIB_LDLIB) \

View file

@ -0,0 +1,25 @@
--- a/libpjproject.pc.in
+++ b/libpjproject.pc.in
@@ -2,8 +2,8 @@
prefix=@PREFIX@
exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCLUDEDIR@
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
Name: libpjproject
Description: Multimedia communication library
--- a/build.mak.in
+++ b/build.mak.in
@@ -314,8 +314,7 @@ export PJ_LIBXX_FILES := $(APP_LIBXX_FIL
# And here are the variables to use if application is using the
# library from the install location (i.e. --prefix)
export PJ_INSTALL_DIR := @prefix@
-export PJ_INSTALL_INC_DIR := @includedir@
export PJ_INSTALL_LIB_DIR := @libdir@
-export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1 @CFLAGS@
+export PJ_INSTALL_CFLAGS := -DPJ_AUTOCONF=1 @CFLAGS@
export PJ_INSTALL_CXXFLAGS := @CXXFLAGS@ $(PJ_INSTALL_CFLAGS)
export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(APP_LDLIBS)

View file

@ -0,0 +1,37 @@
commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e
Author: Kevin Harwell <kharwell@digium.com>
Date: Thu Jun 11 11:11:13 2020 -0500
sip_inv - fix invite session ref count crash
Ensure the session's ref count is only decremented under proper conditons.
For more details see the following issue report:
https://github.com/pjsip/pjproject/issues/2443
Patch supplied by sauwming
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -323,9 +323,19 @@ static void inv_set_state(pjsip_inv_sess
(*mod_inv.cb.on_state_changed)(inv, e);
pjsip_inv_dec_ref(inv);
- /* Only decrement when previous state is not already DISCONNECTED */
+ /* The above callback may change the state, so we need to be careful here
+ * and only decrement inv under the following conditions:
+ * 1. If the state parameter is DISCONNECTED, and previous state is not
+ * already DISCONNECTED.
+ * This is to make sure that dec_ref() is not called more than once.
+ * 2. If current state is PJSIP_INV_STATE_DISCONNECTED.
+ * This is to make sure that dec_ref() is not called if user restarts
+ * inv within the callback. Note that this check must be last since
+ * inv may have already been destroyed.
+ */
if (state == PJSIP_INV_STATE_DISCONNECTED &&
- prev_state != PJSIP_INV_STATE_DISCONNECTED)
+ prev_state != PJSIP_INV_STATE_DISCONNECTED &&
+ inv->state == PJSIP_INV_STATE_DISCONNECTED)
{
pjsip_inv_dec_ref(inv);
}

View file

@ -0,0 +1,35 @@
commit 40dd48d10911f4ff9b8dfbf16428fbc9acc434ba
Author: Riza Sulistyo <trengginas@users.noreply.github.com>
Date: Thu Jul 9 17:47:24 2020 +0700
Modify timer_id check on cancel() (#2463)
* modify timer_id check on cancel().
* modification based on comments.
--- a/pjlib/include/pj/timer.h
+++ b/pjlib/include/pj/timer.h
@@ -120,7 +120,10 @@ typedef struct pj_timer_entry
/**
* Internal unique timer ID, which is assigned by the timer heap.
- * Application should not touch this ID.
+ * Positive values indicate that the timer entry is running,
+ * while -1 means that it's not. Any other value may indicate that it
+ * hasn't been properly initialised or is in a bad state.
+ * Application should not touch this ID.
*/
pj_timer_id_t _timer_id;
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -535,7 +535,7 @@ static int cancel( pj_timer_heap_t *ht,
PJ_CHECK_STACK();
// Check to see if the timer_id is out of range
- if (entry->_timer_id < 0 || (pj_size_t)entry->_timer_id > ht->max_size) {
+ if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {
entry->_timer_id = -1;
return 0;
}

View file

@ -0,0 +1,68 @@
From 78683646c8bc670ec730a42494e075f671a08e28 Mon Sep 17 00:00:00 2001
From: Guido Falsi <mad@madpilot.net>
Date: Mon, 11 May 2020 08:50:39 +0200
Subject: [PATCH] Fix race condition in parallel builds (#2426)
* Some targets residing in `OBJDIRS` are missing a dependency on that directory, which results in a race condition, causing build to fail sometimes due to the directory not existing when running parallel builds.
* The `PJSUA_LIB` variable is not defined anywhere, resulting in an empty value, and no correct dependency on the pjsua shared library for `pjsua2`. The correct variable seems to be `PJSUA_LIB_LIB`, defined at the start of this same `Makefile`.
---
build/rules.mak | 12 ++++++------
pjsip/build/Makefile | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
--- a/build/rules.mak
+++ b/build/rules.mak
@@ -129,7 +129,7 @@ endif
$(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS)
$(CROSS_COMPILE)ld -r -o $@ $(OBJS)
-$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
+$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o | $(OBJDIRS)
@echo Creating kbuild Makefile...
@echo "# Our module name:" > $(OBJDIR)/Makefile
@echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile
@@ -154,27 +154,27 @@ $(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko
cp $(OBJDIR)/$(app).ko ../lib
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp | $(OBJDIRS)
$(CXX) $($(APP)_CXXFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc | $(OBJDIRS)
$(CXX) $($(APP)_CXXFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
--- a/pjsip/build/Makefile
+++ b/pjsip/build/Makefile
@@ -261,7 +261,7 @@ $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME): $(
pjsua2-lib: $(PJSUA2_LIB_LIB)
$(PJSUA2_LIB_SONAME): $(PJSUA2_LIB_LIB)
-$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB) $(PSJUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)
+$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)
$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
pjsip-test: $(TEST_EXE)

View file

@ -0,0 +1,27 @@
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -906,7 +906,7 @@ static pj_status_t process_m_answer( pj_
* after receiving remote answer.
*/
static pj_status_t process_answer(pj_pool_t *pool,
- pjmedia_sdp_session *offer,
+ pjmedia_sdp_session *local_offer,
pjmedia_sdp_session *answer,
pj_bool_t allow_asym,
pjmedia_sdp_session **p_active)
@@ -914,10 +914,14 @@ static pj_status_t process_answer(pj_poo
unsigned omi = 0; /* Offer media index */
unsigned ami = 0; /* Answer media index */
pj_bool_t has_active = PJ_FALSE;
+ pjmedia_sdp_session *offer;
pj_status_t status;
/* Check arguments. */
- PJ_ASSERT_RETURN(pool && offer && answer && p_active, PJ_EINVAL);
+ PJ_ASSERT_RETURN(pool && local_offer && answer && p_active, PJ_EINVAL);
+
+ /* Duplicate local offer SDP. */
+ offer = pjmedia_sdp_session_clone(pool, local_offer);
/* Check that media count match between offer and answer */
// Ticket #527, different media count is allowed for more interoperability,

View file

@ -0,0 +1,32 @@
From ce18018cc17bef8f80c08686e3a7b28384ef3ba5 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
Date: Mon, 12 Oct 2020 13:31:25 +0800
Subject: [PATCH] Fix incorrect copying of destination info when creating
CANCEL (#2546)
---
pjsip/src/pjsip/sip_util.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -779,14 +779,14 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_c
pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);
}
- /* Copy the destination host name from the original request */
- pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
- &req_tdata->dest_info.name);
-
- /* Finally copy the destination info from the original request */
+ /* Copy the destination info from the original request */
pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
sizeof(req_tdata->dest_info));
+ /* Finally, copy the destination host name from the original request */
+ pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
+ &req_tdata->dest_info.name);
+
/* Done.
* Return the transmit buffer containing the CANCEL request.
*/

View file

@ -1,8 +1,6 @@
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index 3b85b4273..a14009662 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modi
{
pjmedia_sdp_session *new_offer;
pjmedia_sdp_session *old_offer;
@ -10,7 +8,7 @@ index 3b85b4273..a14009662 100644
unsigned oi; /* old offer media index */
pj_status_t status;
@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modi
/* Change state to STATE_LOCAL_OFFER */
neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;

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));

View file

@ -0,0 +1,132 @@
From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Wed, 16 Jun 2021 12:15:29 +0700
Subject: [PATCH 2/2] - Fix silly mistake: accepted active socket created
without group lock in SSL socket. - Replace assertion with normal validation
check of SSL socket instance in OpenSSL verification callback (verify_cb())
to avoid crash, e.g: if somehow race condition with SSL socket destroy
happens or OpenSSL application data index somehow gets corrupted.
---
pjlib/src/pj/ssl_sock_imp_common.c | 3 +-
pjlib/src/pj/ssl_sock_ossl.c | 45 +++++++++++++++++++++++++-----
2 files changed, 40 insertions(+), 8 deletions(-)
--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
@@ -949,6 +949,7 @@ static pj_bool_t asock_on_accept_complet
/* Create active socket */
pj_activesock_cfg_default(&asock_cfg);
+ asock_cfg.grp_lock = ssock->param.grp_lock;
asock_cfg.async_cnt = ssock->param.async_cnt;
asock_cfg.concurrency = ssock->param.concurrency;
asock_cfg.whole_data = PJ_TRUE;
@@ -964,7 +965,7 @@ static pj_bool_t asock_on_accept_complet
goto on_return;
pj_grp_lock_add_ref(glock);
- asock_cfg.grp_lock = ssock->param.grp_lock = glock;
+ ssock->param.grp_lock = glock;
pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
ssl_on_destroy);
}
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -327,7 +327,8 @@ static pj_status_t STATUS_FROM_SSL_ERR(c
ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);
}
- ssock->last_err = err;
+ if (ssock)
+ ssock->last_err = err;
return GET_STATUS_FROM_SSL_ERR(err);
}
@@ -344,7 +345,8 @@ static pj_status_t STATUS_FROM_SSL_ERR2(
/* Dig for more from OpenSSL error queue */
SSLLogErrors(action, ret, err, len, ssock);
- ssock->last_err = ssl_err;
+ if (ssock)
+ ssock->last_err = ssl_err;
return GET_STATUS_FROM_SSL_ERR(ssl_err);
}
@@ -587,6 +589,13 @@ static pj_status_t init_openssl(void)
/* Create OpenSSL application data index for SSL socket */
sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL);
+ if (sslsock_idx == -1) {
+ status = STATUS_FROM_SSL_ERR2("Init", NULL, -1, ERR_get_error(), 0);
+ PJ_LOG(1,(THIS_FILE,
+ "Fatal error: failed to get application data index for "
+ "SSL socket"));
+ return status;
+ }
return status;
}
@@ -614,21 +623,36 @@ static int password_cb(char *buf, int nu
}
-/* SSL password callback. */
+/* SSL certificate verification result callback.
+ * Note that this callback seems to be always called from library worker
+ * thread, e.g: active socket on_read_complete callback, which should have
+ * already been equipped with race condition avoidance mechanism (should not
+ * be destroyed while callback is being invoked).
+ */
static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
- pj_ssl_sock_t *ssock;
- SSL *ossl_ssl;
+ pj_ssl_sock_t *ssock = NULL;
+ SSL *ossl_ssl = NULL;
int err;
/* Get SSL instance */
ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
- pj_assert(ossl_ssl);
+ if (!ossl_ssl) {
+ PJ_LOG(1,(THIS_FILE,
+ "SSL verification callback failed to get SSL instance"));
+ goto on_return;
+ }
/* Get SSL socket instance */
ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx);
- pj_assert(ssock);
+ if (!ssock) {
+ /* SSL socket may have been destroyed */
+ PJ_LOG(1,(THIS_FILE,
+ "SSL verification callback failed to get SSL socket "
+ "instance (sslsock_idx=%d).", sslsock_idx));
+ goto on_return;
+ }
/* Store verification status */
err = X509_STORE_CTX_get_error(x509_ctx);
@@ -706,6 +730,7 @@ static int verify_cb(int preverify_ok, X
if (PJ_FALSE == ssock->param.verify_peer)
preverify_ok = 1;
+on_return:
return preverify_ok;
}
@@ -1213,6 +1238,12 @@ static void ssl_destroy(pj_ssl_sock_t *s
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
{
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
+
+ /* Detach from SSL instance */
+ if (ossock->ossl_ssl) {
+ SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
+ }
+
/**
* Avoid calling SSL_shutdown() if handshake wasn't completed.
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during an

View file

@ -0,0 +1,27 @@
From 2ae784030b0d9cf217c3d562af20e4967f19a3dc Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@sangoma.com>
Date: Tue, 14 Sep 2021 10:47:29 -0600
Subject: [PATCH] pjmedia_sdp_attr_get_rtpmap: Strip param trailing whitespace
Use pj_scan_get() to parse the param part of rtpmap so
trailing whitespace is automatically stripped.
Fixes #2827
---
pjmedia/src/pjmedia/sdp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/pjmedia/src/pjmedia/sdp.c
+++ b/pjmedia/src/pjmedia/sdp.c
@@ -313,9 +313,9 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get
/* Expecting either '/' or EOF */
if (*scanner.curptr == '/') {
+ /* Skip the '/' */
pj_scan_get_char(&scanner);
- rtpmap->param.ptr = scanner.curptr;
- rtpmap->param.slen = scanner.end - scanner.curptr;
+ pj_scan_get(&scanner, &cs_token, &rtpmap->param);
} else {
rtpmap->param.slen = 0;
}

View file

@ -1,35 +0,0 @@
From 42e5ee52e1113d24b7125e29669022c35e87693f Mon Sep 17 00:00:00 2001
From: Sauw Ming <ming@teluu.com>
Date: Wed, 26 Sep 2018 00:56:51 +0000
Subject: [PATCH] Re #2147 (misc): Fixed build error of undefined reference to
`pjmedia_srtp_enum_crypto' if PJMEDIA_HAS_SRTP is disabled.
Thanks to Alexei Gradinari for the patch
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5891 74dad513-b988-da41-8d7b-12977e46ad98
---
pjsip/src/pjsua2/endpoint.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/pjsip/src/pjsua2/endpoint.cpp
+++ b/pjsip/src/pjsua2/endpoint.cpp
@@ -2145,14 +2145,16 @@ void Endpoint::resetVideoCodecParam(cons
*/
StringVector Endpoint::srtpCryptoEnum() throw(Error)
{
+ StringVector result;
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
unsigned cnt = PJMEDIA_SRTP_MAX_CRYPTOS;
pjmedia_srtp_crypto cryptos[PJMEDIA_SRTP_MAX_CRYPTOS];
- StringVector result;
PJSUA2_CHECK_EXPR(pjmedia_srtp_enum_crypto(&cnt, cryptos));
for (unsigned i = 0; i < cnt; ++i)
result.push_back(pj2Str(cryptos[i].name));
+#endif
return result;
}

View file

@ -1,32 +0,0 @@
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -4185,6 +4185,29 @@ static void inv_on_state_calling( pjsip_
if (tsx->status_code != 100) {
+ if (inv->role == PJSIP_ROLE_UAC) {
+ pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+ pjsip_allow_hdr *allow = NULL;
+ pjsip_msg *msg = rdata->msg_info.msg;
+
+ if (msg) {
+ allow = (pjsip_allow_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_ALLOW,
+ NULL);
+ }
+ if (allow) {
+ unsigned i;
+ const pj_str_t STR_UPDATE = { "UPDATE", 6 };
+
+ for (i=0; i<allow->count; ++i) {
+ if (pj_stricmp(&allow->values[i], &STR_UPDATE)==0) {
+ /* UPDATE is present in Allow */
+ inv->options |= PJSIP_INV_SUPPORT_UPDATE;
+ break;
+ }
+ }
+ }
+ }
+
if (dlg->remote.info->tag.slen)
inv_set_state(inv, PJSIP_INV_STATE_EARLY, e);

View file

@ -1,37 +0,0 @@
From 1fed39fe1488abd654a5488b5e6ad59b4b973331 Mon Sep 17 00:00:00 2001
From: nanang <nanang@localhost>
Date: Tue, 8 Jan 2019 09:07:47 +0000
Subject: [PATCH 1/5] Fixed #2172: Avoid double reference counter decrements in
timer in the scenario of race condition between pj_timer_heap_cancel() and
pj_timer_heap_poll().
---
pjlib/src/pj/timer.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -580,13 +580,16 @@ static int cancel_timer(pj_timer_heap_t
lock_timer_heap(ht);
count = cancel(ht, entry, flags | F_DONT_CALL);
- if (flags & F_SET_ID) {
- entry->id = id_val;
- }
- if (entry->_grp_lock) {
- pj_grp_lock_t *grp_lock = entry->_grp_lock;
- entry->_grp_lock = NULL;
- pj_grp_lock_dec_ref(grp_lock);
+ if (count > 0) {
+ /* Timer entry found & cancelled */
+ if (flags & F_SET_ID) {
+ entry->id = id_val;
+ }
+ if (entry->_grp_lock) {
+ pj_grp_lock_t *grp_lock = entry->_grp_lock;
+ entry->_grp_lock = NULL;
+ pj_grp_lock_dec_ref(grp_lock);
+ }
}
unlock_timer_heap(ht);

View file

@ -1,32 +0,0 @@
From 9f57a5728aaec1949908bf7bbd15768fce74e315 Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Wed, 13 Feb 2019 06:51:09 +0000
Subject: [PATCH] Re #2176: Removed pop_freelist() + push_freelist() after
remove_node() as they are not only unnecessary, they cause problem.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5934 74dad513-b988-da41-8d7b-12977e46ad98
---
pjlib/src/pj/timer.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -633,7 +633,8 @@ PJ_DEF(unsigned) pj_timer_heap_poll( pj_
{
pj_timer_entry *node = remove_node(ht, 0);
/* Avoid re-use of this timer until the callback is done. */
- pj_timer_id_t node_timer_id = pop_freelist(ht);
+ ///Not necessary, even causes problem (see also #2176).
+ ///pj_timer_id_t node_timer_id = pop_freelist(ht);
pj_grp_lock_t *grp_lock;
++count;
@@ -653,7 +654,7 @@ PJ_DEF(unsigned) pj_timer_heap_poll( pj_
lock_timer_heap(ht);
/* Now, the timer is really free for re-use. */
- push_freelist(ht, node_timer_id);
+ ///push_freelist(ht, node_timer_id);
}
if (ht->cur_size && next_delay) {
*next_delay = ht->heap[0]->_timer_value;

View file

@ -8,14 +8,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=asterisk16-chan-lantiq
PKG_VERSION:=20180215
PKG_RELEASE:=2
PKG_VERSION:=20210911
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/kochstefan/asterisk_channel_lantiq.git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=c9d68dd06fcd46ac7985df45f8c2b8833e658f8e
PKG_MIRROR_HASH:=8666c18b24adf9da3ddf12306fcf0a8b4f56860c256b172bd0ba5c2a7a3ab25e
PKG_SOURCE_VERSION:=2f029ec8778420538c8151c6aceba0f7b44b07c9
PKG_MIRROR_HASH:=72ce3cb4a081c6ea39c9814fba03997ef32b48e927469508222f5641fe987c65
PKG_SOURCE_PROTO:=git
PKG_LICENSE:=GPL-2.0
@ -43,12 +43,6 @@ define Package/$(PKG_NAME)/conffiles
/etc/asterisk/lantiq.conf
endef
define Build/Prepare
$(call Build/Prepare/Default)
$(INSTALL_DATA) ./files/default.exports \
$(PKG_BUILD_DIR)/src/channels/chan_lantiq.exports
endef
define Build/Compile
cd $(PKG_BUILD_DIR)/src/channels && \
$(TARGET_CC) -o chan_lantiq.o -c chan_lantiq.c -MD -MT chan_lantiq.o \

View file

@ -1,8 +0,0 @@
{
global:
/* See main/asterisk.exports.in for an explanation why this is
* needed. */
_IO_stdin_used;
local:
*;
};

View file

@ -1,43 +0,0 @@
commit 30f9a094c1c60e0d68e4ea189f48ecb47aebb485
Author: arny <arnysch@gmx.net>
Date: Thu May 2 20:07:28 2019 +0200
Use ast_malloc and ast_free instead of malloc and free
in order to get rid of build errors with asterisk16 in OpenWrt
Signed-off-by: arny <arnysch@gmx.net>
diff --git a/src/channels/chan_lantiq.c b/src/channels/chan_lantiq.c
index a8fc869..90002ab 100644
--- a/src/channels/chan_lantiq.c
+++ b/src/channels/chan_lantiq.c
@@ -563,9 +563,9 @@ lantiq_dev_binary_buffer_create(const char *path, uint8_t **ppBuf, uint32_t *pBu
goto on_exit;
}
- *ppBuf = malloc(file_stat.st_size);
+ *ppBuf = ast_malloc(file_stat.st_size);
if (*ppBuf == NULL) {
- ast_log(LOG_ERROR, "binary file %s memory allocation failed\n", path);
+ // Message already logged by ast_malloc
goto on_exit;
}
@@ -583,7 +583,7 @@ on_exit:
fclose(fd);
if (*ppBuf != NULL && status)
- free(*ppBuf);
+ ast_free(*ppBuf);
return status;
}
@@ -609,7 +609,7 @@ static int32_t lantiq_dev_firmware_download(int32_t fd, const char *path)
}
if (firmware != NULL)
- free(firmware);
+ ast_free(firmware);
return 0;
}

View file

@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk
AST_MAJOR_VERSION:=16
PKG_NAME:=asterisk$(AST_MAJOR_VERSION)
PKG_VERSION:=$(AST_MAJOR_VERSION).3.0
PKG_RELEASE:=9
PKG_VERSION:=$(AST_MAJOR_VERSION).22.0
PKG_RELEASE:=1
PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases
PKG_HASH:=8b22ee7c0c0b5557eff273118703c6fce8b743c12bbeb679ed86b3f197444a8e
PKG_HASH:=46992482762818e096d92654b9ac96d42fa9505ad4bc8e628a683413793ab26f
PKG_BUILD_DIR:=$(BUILD_DIR)/asterisk-$(PKG_VERSION)
PKG_BUILD_DEPENDS:=libxml2/host
@ -43,7 +43,9 @@ MODULES_AVAILABLE:= \
app-agent-pool \
app-alarmreceiver \
app-amd \
app-attended-transfer \
app-authenticate \
app-blind-transfer \
app-bridgeaddchan \
app-bridgewait \
app-celgenuserevent \
@ -57,6 +59,7 @@ MODULES_AVAILABLE:= \
app-directed-pickup \
app-directory \
app-disa \
app-dtmfstore \
app-dumpchan \
app-exec \
app-externalivr \
@ -67,6 +70,7 @@ MODULES_AVAILABLE:= \
app-ices \
app-image \
app-ivrdemo \
app-mf \
app-milliwatt \
app-minivm \
app-mixmonitor \
@ -80,6 +84,7 @@ MODULES_AVAILABLE:= \
app-read \
app-readexten \
app-record \
app-reload \
app-saycounted \
app-sayunixtime \
app-senddtmf \
@ -99,6 +104,7 @@ MODULES_AVAILABLE:= \
app-url \
app-userevent \
app-verbose \
app-waitforcond \
app-waitforring \
app-waitforsilence \
app-waituntil \
@ -176,6 +182,7 @@ MODULES_AVAILABLE:= \
func-enum \
func-env \
func-extstate \
func-frame-drop \
func-frame-trace \
func-global \
func-groupcount \
@ -192,6 +199,8 @@ MODULES_AVAILABLE:= \
func-presencestate \
func-rand \
func-realtime \
func-sayfiles \
func-scramble \
func-sha1 \
func-shell \
func-sorcery \
@ -271,6 +280,7 @@ MODULES_AVAILABLE:= \
res-parking \
res-phoneprov \
res-pjsip-phoneprov \
res-pjsip-stir-shaken \
res-pjproject \
res-pktccops \
res-realtime \
@ -293,10 +303,11 @@ MODULES_AVAILABLE:= \
res-stasis-recording \
res-stasis-snoop \
res-statsd \
res-stir-shaken \
res-stun-monitor \
res-timing-dahdi \
res-timing-pthread \
res-timing-timerfd \
res-tonedetect \
res-xmpp \
voicemail
@ -485,7 +496,7 @@ AST_CFG_FILES:= \
AST_EMB_MODULES:=\
app_dial app_echo app_macro app_playback \
func_callerid func_logic func_strings func_timeout \
pbx_config res_crypto
pbx_config res_crypto res_timing_timerfd
define Package/$(PKG_NAME)/install
$(call Package/$(PKG_NAME)/install/lib,$(1),libasteriskssl)
@ -757,7 +768,9 @@ $(eval $(call BuildAsteriskModule,app-adsiprog,ADSI programming,Asterisk ADSI pr
$(eval $(call BuildAsteriskModule,app-agent-pool,Call center agent pool,Call center agent pool applications.,,agents.conf,app_agent_pool,,))
$(eval $(call BuildAsteriskModule,app-alarmreceiver,Alarm receiver,Alarm receiver for Asterisk.,,,app_alarmreceiver,,))
$(eval $(call BuildAsteriskModule,app-amd,Answering machine detection,Answering Machine Detection application.,,amd.conf,app_amd,,))
$(eval $(call BuildAsteriskModule,app-attended-transfer,Attended transfer,Queues up an attended transfer to a given extension.,,,app_attended_transfer,,))
$(eval $(call BuildAsteriskModule,app-authenticate,Authenticate commands,Authentication application.,,,app_authenticate,,))
$(eval $(call BuildAsteriskModule,app-blind-transfer,Blind transfer,Redirects all channels currently bridged to the caller channel to a specified destination.,,,app_blind_transfer,,))
$(eval $(call BuildAsteriskModule,app-bridgeaddchan,Bridge add channel,Bridge-add-channel application.,,,app_bridgeaddchan,,))
$(eval $(call BuildAsteriskModule,app-bridgewait,Holding bridge,Application to place a channel into a holding bridge.,+$(PKG_NAME)-bridge-holding,,app_bridgewait,,))
$(eval $(call BuildAsteriskModule,app-celgenuserevent,User-defined CEL event,Generate a user defined CEL event.,,,app_celgenuserevent,,))
@ -771,16 +784,18 @@ $(eval $(call BuildAsteriskModule,app-dictate,Virtual dictation machine,Virtual
$(eval $(call BuildAsteriskModule,app-directed-pickup,Directed call pickup,Directed call pickup application.,,,app_directed_pickup,,))
$(eval $(call BuildAsteriskModule,app-directory,Extension directory,Extension directory.,,,app_directory,,))
$(eval $(call BuildAsteriskModule,app-disa,Direct Inward System Access,Direct Inward System Access application.,,,app_disa,,))
$(eval $(call BuildAsteriskModule,app-dtmfstore,DTMF storage,Technology independent async DTMF storage.,,,app_dtmfstore,,))
$(eval $(call BuildAsteriskModule,app-dumpchan,Dump info about channel,Dump info about the calling channel.,,,app_dumpchan,,))
$(eval $(call BuildAsteriskModule,app-exec,Exec application,Executes dialplan applications.,,,app_exec,,))
$(eval $(call BuildAsteriskModule,app-externalivr,External IVR interface,External IVR interface application.,,,app_externalivr,,))
$(eval $(call BuildAsteriskModule,app-festival,Simple festival interface,Simple Festival interface.,,festival.conf,app_festival,,))
$(eval $(call BuildAsteriskModule,app-flash,Flash channel,Flash channel application.,+$(PKG_NAME)-chan-dahdi,,app_flash,,))
$(eval $(call BuildAsteriskModule,app-followme,Find-me/follow-me,Find-Me/Follow-Me application.,,followme.conf,app_followme,,))
$(eval $(call BuildAsteriskModule,app-getcpeid,Get ADSI CPE ID,Get ADSI CPE ID.,,,app_getcpeid,,))
$(eval $(call BuildAsteriskModule,app-getcpeid,Get ADSI CPE ID,Get ADSI CPE ID.,+$(PKG_NAME)-res-adsi,,app_getcpeid,,))
$(eval $(call BuildAsteriskModule,app-ices,Encode and stream,Encode and stream via Icecast and IceS.,,,app_ices,,))
$(eval $(call BuildAsteriskModule,app-image,Image transmission,Image transmission application.,,,app_image,,))
$(eval $(call BuildAsteriskModule,app-ivrdemo,IVR demo,IVR demo application.,,,app_ivrdemo,,))
$(eval $(call BuildAsteriskModule,app-mf,MF digits,Send MF digits Application.,,,app_mf,,))
$(eval $(call BuildAsteriskModule,app-milliwatt,Digital milliwatt [mu-law] test app,Digital milliwatt test application.,,,app_milliwatt,,))
$(eval $(call BuildAsteriskModule,app-minivm,Minimal voicemail system,A minimal voicemail e-mail system.,,extensions_minivm.conf minivm.conf,app_minivm,,))
$(eval $(call BuildAsteriskModule,app-mixmonitor,Record a call and mix the audio,Mixed audio monitoring application.,,,app_mixmonitor,,))
@ -794,6 +809,7 @@ $(eval $(call BuildAsteriskModule,app-queue,True Call Queueing,True call queuein
$(eval $(call BuildAsteriskModule,app-read,Variable read,Read variable application.,,,app_read,,))
$(eval $(call BuildAsteriskModule,app-readexten,Extension to variable,Read and evaluate extension validity.,,,app_readexten,,))
$(eval $(call BuildAsteriskModule,app-record,Record sound file,Trivial record application.,,,app_record,,))
$(eval $(call BuildAsteriskModule,app-reload,Reload,Reload module[s].,,,app_reload,,))
$(eval $(call BuildAsteriskModule,app-saycounted,Decline words,Decline words according to channel language.,,,app_saycounted,,))
$(eval $(call BuildAsteriskModule,app-sayunixtime,Say Unix time,Say time.,,,app_sayunixtime,,))
$(eval $(call BuildAsteriskModule,app-senddtmf,Send DTMF digits,Send DTMF digits application.,,,app_senddtmf,,))
@ -813,6 +829,7 @@ $(eval $(call BuildAsteriskModule,app-transfer,Transfers caller to other ext,Tra
$(eval $(call BuildAsteriskModule,app-url,Send URL,Send URL applications.,,,app_url,,))
$(eval $(call BuildAsteriskModule,app-userevent,Custom user event,Custom user event application.,,,app_userevent,,))
$(eval $(call BuildAsteriskModule,app-verbose,Verbose logging,Send verbose output.,,,app_verbose,,))
$(eval $(call BuildAsteriskModule,app-waitforcond,Wait for condition,Wait until condition is true.,,,app_waitforcond,,))
$(eval $(call BuildAsteriskModule,app-waitforring,Wait for first ring,Waits until first ring after time.,,,app_waitforring,,))
$(eval $(call BuildAsteriskModule,app-waitforsilence,Wait for silence/noise,Wait for silence/noise.,,,app_waitforsilence,,))
$(eval $(call BuildAsteriskModule,app-waituntil,Sleep,Wait until specified time.,,,app_waituntil,,))
@ -834,14 +851,14 @@ $(eval $(call BuildAsteriskModule,chan-alsa,ALSA channel,ALSA console channel dr
$(eval $(call BuildAsteriskModule,chan-bridge-media,Bridge media channel driver,Bridge media channel driver.,,,chan_bridge_media,,))
$(eval $(call BuildAsteriskModule,chan-console,Console channel driver,Console channel driver.,+portaudio,console.conf,chan_console,,))
$(eval $(call BuildAsteriskModule,chan-dahdi,DAHDI channel,DAHDI telephony.,+dahdi-tools-libtonezone +kmod-dahdi +libpri @!aarch64,chan_dahdi.conf,chan_dahdi,,))
$(eval $(call BuildAsteriskModule,chan-iax2,IAX2 channel,Inter Asterisk eXchange.,+$(PKG_NAME)-res-timing-timerfd,iax.conf iaxprov.conf,chan_iax2,,))
$(eval $(call BuildAsteriskModule,chan-iax2,IAX2 channel,Inter Asterisk eXchange.,,iax.conf iaxprov.conf,chan_iax2,,))
$(eval $(call BuildAsteriskModule,chan-mgcp,MGCP,Media Gateway Control Protocol.,,mgcp.conf,chan_mgcp,,))
$(eval $(call BuildAsteriskModule,chan-mobile,Bluetooth channel,Bluetooth mobile device channel driver.,+bluez-libs,chan_mobile.conf,chan_mobile,,))
$(eval $(call BuildAsteriskModule,chan-motif,Jingle channel,Motif Jingle channel driver.,+$(PKG_NAME)-res-xmpp,motif.conf,chan_motif,,))
$(eval $(call BuildAsteriskModule,chan-ooh323,H.323 channel,Objective Systems H.323 channel.,,ooh323.conf,chan_ooh323,,))
$(eval $(call BuildAsteriskModule,chan-oss,OSS channel,OSS console channel driver.,,oss.conf,chan_oss,,))
$(eval $(call BuildAsteriskModule,chan-phone,Linux telephony API,Linux telephony API support.,,phone.conf,chan_phone,,))
$(eval $(call BuildAsteriskModule,chan-rtp,RTP media channel,RTP media channel.,,,chan_rtp,,))
$(eval $(call BuildAsteriskModule,chan-rtp,RTP media channel,RTP media channel.,+$(PKG_NAME)-res-rtp-multicast,,chan_rtp,,))
$(eval $(call BuildAsteriskModule,chan-sip,SIP channel,Session Initiation Protocol.,+$(PKG_NAME)-app-confbridge,sip.conf sip_notify.conf,chan_sip,,))
$(eval $(call BuildAsteriskModule,chan-skinny,Skinny channel,Skinny Client Control Protocol.,,skinny.conf,chan_skinny,,))
$(eval $(call BuildAsteriskModule,chan-unistim,Unistim channel,UNISTIM protocol.,,unistim.conf,chan_unistim,,))
@ -890,6 +907,7 @@ $(eval $(call BuildAsteriskModule,func-dialplan,Dialplan context/extension/prior
$(eval $(call BuildAsteriskModule,func-enum,ENUM,ENUM related dialplan functions.,,enum.conf,func_enum,,))
$(eval $(call BuildAsteriskModule,func-env,Environment functions,Environment/filesystem dialplan functions.,,,func_env,,))
$(eval $(call BuildAsteriskModule,func-extstate,Hinted extension state,Gets the state of an extension in the dialplan.,,,func_extstate,,))
$(eval $(call BuildAsteriskModule,func-frame-drop,Frame drop,Function to drop frames on a channel.,,,func_frame_drop,,))
$(eval $(call BuildAsteriskModule,func-frame-trace,Frame trace for internal ast_frame debugging,Frame trace for internal ast_frame debugging.,,,func_frame_trace,,))
$(eval $(call BuildAsteriskModule,func-global,Global variable,Variable dialplan functions.,,,func_global,,))
$(eval $(call BuildAsteriskModule,func-groupcount,Group count,Channel group dialplan functions.,,,func_groupcount,,))
@ -906,6 +924,8 @@ $(eval $(call BuildAsteriskModule,func-pitchshift,Audio effects dialplan functio
$(eval $(call BuildAsteriskModule,func-presencestate,Hinted presence state,Gets or sets a presence state in the dialplan.,,,func_presencestate,,))
$(eval $(call BuildAsteriskModule,func-rand,RAND dialplan function,Random number dialplan function.,,,func_rand,,))
$(eval $(call BuildAsteriskModule,func-realtime,REALTIME dialplan function,Read/write/store/destroy values from a realtime repository.,,,func_realtime,,))
$(eval $(call BuildAsteriskModule,func-sayfiles,Say files,Say application files.,,,func_sayfiles,,))
$(eval $(call BuildAsteriskModule,func-scramble,Scramble,Frequency inverting voice scrambler.,,,func_scramble,,))
$(eval $(call BuildAsteriskModule,func-sha1,SHA-1 computation dialplan function,SHA-1 computation dialplan function.,,,func_sha1,,))
$(eval $(call BuildAsteriskModule,func-shell,Shell,Collects the output generated by a command executed by the system shell.,,,func_shell,,))
$(eval $(call BuildAsteriskModule,func-sorcery,Get a field from a sorcery object,Get a field from a sorcery object.,,,func_sorcery,,))
@ -960,7 +980,7 @@ $(eval $(call BuildAsteriskModule,res-hep,HEPv3 API,HEPv3 API.,,hep.conf,res_hep
$(eval $(call BuildAsteriskModule,res-hep-pjsip,PJSIP HEPv3 Logger,PJSIP HEPv3 logger.,+$(PKG_NAME)-res-hep +$(PKG_NAME)-pjsip,,res_hep_pjsip,,))
$(eval $(call BuildAsteriskModule,res-hep-rtcp,RTCP HEPv3 Logger,RTCP HEPv3 logger.,+$(PKG_NAME)-res-hep,,res_hep_rtcp,,))
$(eval $(call BuildAsteriskModule,res-fax-spandsp,Spandsp T.38 and G.711,Spandsp G.711 and T.38 FAX technologies.,+$(PKG_NAME)-res-fax +libspandsp +libtiff,,res_fax_spandsp,,))
$(eval $(call BuildAsteriskModule,res-fax,FAX modules,Generic FAX applications.,+$(PKG_NAME)-res-timing-pthread,res_fax.conf,res_fax,,))
$(eval $(call BuildAsteriskModule,res-fax,FAX modules,Generic FAX applications.,,res_fax.conf,res_fax,,))
$(eval $(call BuildAsteriskModule,res-format-attr-celt,CELT format attribute module,CELT format attribute module.,,,res_format_attr_celt,,))
$(eval $(call BuildAsteriskModule,res-format-attr-g729,G.729 format attribute module,G.729 format attribute module.,,,res_format_attr_g729,,))
$(eval $(call BuildAsteriskModule,res-format-attr-h263,H.263 format attribute module,H.263 format attribute module.,,,res_format_attr_h263,,))
@ -984,8 +1004,9 @@ $(eval $(call BuildAsteriskModule,res-mwi-external,Core external MWI resource,Co
$(eval $(call BuildAsteriskModule,res-mwi-external-ami,AMI for external MWI,AMI support for external MWI.,+$(PKG_NAME)-res-mwi-external,,res_mwi_external_ami,,))
$(eval $(call BuildAsteriskModule,res-parking,Phone Parking,Call parking resource.,+$(PKG_NAME)-bridge-holding,res_parking.conf,res_parking,,))
$(eval $(call BuildAsteriskModule,res-phoneprov,Phone Provisioning,HTTP phone provisioning.,,phoneprov.conf,res_phoneprov,,))
$(eval $(call BuildAsteriskModule,res-pjsip-stir-shaken,PJSIP STIR/SHAKEN resource,PJSIP STIR/SHAKEN resource module.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-stir-shaken,,res_pjsip_stir_shaken,,))
$(eval $(call BuildAsteriskModule,res-pjsip-phoneprov,PJSIP Phone Provisioning,PJSIP phone provisioning.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-phoneprov,,res_pjsip_phoneprov_provider,,))
$(eval $(call BuildAsteriskModule,res-pjproject,Bridge PJPROJECT to Asterisk logging,PJProject log and utility support.,+libpj +libpjlib-util +libpjmedia +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +libpjsua +libpjsua2 +libsrtp2,pjproject.conf,res_pjproject,,))
$(eval $(call BuildAsteriskModule,res-pjproject,Bridge PJPROJECT to Asterisk logging,PJProject log and utility support.,+libpj +libpjlib-util +libpjmedia +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +libpjsua +libpjsua2 +libsrtp2 +$(PKG_NAME)-res-sorcery,pjproject.conf,res_pjproject,,))
$(eval $(call BuildAsteriskModule,res-pktccops,PktcCOPS manager for MGCP,PktcCOPS manager for MGCP.,,res_pktccops.conf,res_pktccops,,))
$(eval $(call BuildAsteriskModule,res-realtime,RealTime CLI,Realtime data lookup/rewrite.,,,res_realtime,,))
$(eval $(call BuildAsteriskModule,res-remb-modifier,REMB modifier,REMB modifier module.,,,res_remb_modifier,,))
@ -1007,10 +1028,11 @@ $(eval $(call BuildAsteriskModule,res-stasis-playback,Stasis application playbac
$(eval $(call BuildAsteriskModule,res-stasis-recording,Stasis application recording,Stasis application recording support.,+$(PKG_NAME)-res-stasis,,res_stasis_recording,,))
$(eval $(call BuildAsteriskModule,res-stasis-snoop,Stasis application snoop,Stasis application snoop support.,+$(PKG_NAME)-res-stasis-recording,,res_stasis_snoop,,))
$(eval $(call BuildAsteriskModule,res-statsd,statsd client,Statsd client support.,,statsd.conf,res_statsd,,))
$(eval $(call BuildAsteriskModule,res-stir-shaken,STIR/SHAKEN resource module,STIR/SHAKEN resource module.,+$(PKG_NAME)-curl,stir_shaken.conf,res_stir_shaken,,))
$(eval $(call BuildAsteriskModule,res-stun-monitor,STUN monitoring,STUN network monitor.,,res_stun_monitor.conf,res_stun_monitor,,))
$(eval $(call BuildAsteriskModule,res-timing-dahdi,DAHDI Timing Interface,DAHDI timing interface.,+$(PKG_NAME)-chan-dahdi,,res_timing_dahdi,,))
$(eval $(call BuildAsteriskModule,res-timing-pthread,pthread Timing Interface,pthread timing interface.,,,res_timing_pthread,,))
$(eval $(call BuildAsteriskModule,res-timing-timerfd,Timerfd Timing Interface,Timerfd timing interface.,,,res_timing_timerfd,,))
$(eval $(call BuildAsteriskModule,res-tonedetect,Tone detection,Tone detection module.,,,res_tonedetect,,))
$(eval $(call BuildAsteriskModule,res-xmpp,XMPP client and component module,Asterisk XMPP interface.,+libiksemel +libopenssl,xmpp.conf,res_xmpp,,))
$(eval $(call BuildAsteriskModule,voicemail,Voicemail,Voicemail modules.,+$(PKG_NAME)-res-adsi +$(PKG_NAME)-res-smdi,voicemail.conf,app_voicemail,vm-*,))

View file

@ -1,6 +1,6 @@
--- a/configure.ac
+++ b/configure.ac
@@ -1018,15 +1018,18 @@ AC_LINK_IFELSE(
@@ -1033,15 +1033,18 @@ AC_LINK_IFELSE(
# Some platforms define sem_init(), but only support sem_open(). joyous.
AC_MSG_CHECKING(for working unnamed semaphores)

View file

@ -18,7 +18,7 @@ Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
--- a/configure.ac
+++ b/configure.ac
@@ -1412,7 +1412,11 @@ AC_LINK_IFELSE(
@@ -1427,7 +1427,11 @@ AC_LINK_IFELSE(
#include <arpa/nameser.h>
#endif
#include <resolv.h>],

View file

@ -1,38 +0,0 @@
From 06e8d5ad8e4728a716bf357c8d7f70367ae10280 Mon Sep 17 00:00:00 2001
From: Sebastian Kemper <sebastian_ml@gmx.net>
Date: Sun, 12 Jan 2020 12:37:46 +0100
Subject: [PATCH] check_expr2: fix cross-compile/hardening issues
When building check_expr2 with ASLR PIE hardening enabled the linker
fails. This is resolved by adding the regular compiler flags when
building the object files from ast_expr2f.c and ast_expr2.c.
Note: The STANDALONE define is removed because it is already defined in
_ASTCFLAGS. YY_NO_INPUT is defined so that the compile survives
'--enable-dev-mode'.
ASTERISK-28685 #close
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Change-Id: If435b7db9f9ad8266245bda51c81c220f9658915
Taken just Makefile changes from commit: 06e8d5ad8e4728a716bf357c8d7f70367ae10280
---
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -180,14 +180,13 @@ conf2ael: conf2ael.o ast_expr2f.o ast_ex
check_expr2: $(ASTTOPDIR)/main/ast_expr2f.c $(ASTTOPDIR)/main/ast_expr2.c $(ASTTOPDIR)/main/ast_expr2.h astmm.o
$(ECHO_PREFIX) echo " [CC] ast_expr2f.c -> ast_expr2fz.o"
- $(CC) -g -c -I$(ASTTOPDIR)/include -DSTANDALONE $(ASTTOPDIR)/main/ast_expr2f.c -o ast_expr2fz.o
+ $(CC) -g -c -I$(ASTTOPDIR)/include $(_ASTCFLAGS) $(ASTTOPDIR)/main/ast_expr2f.c -o ast_expr2fz.o
$(ECHO_PREFIX) echo " [CC] ast_expr2.c -> ast_expr2z.o"
- $(CC) -g -c -I$(ASTTOPDIR)/include -DSTANDALONE2 $(ASTTOPDIR)/main/ast_expr2.c -o ast_expr2z.o
+ $(CC) -g -c -I$(ASTTOPDIR)/include $(_ASTCFLAGS) -DSTANDALONE2 $(ASTTOPDIR)/main/ast_expr2.c -o ast_expr2z.o
$(ECHO_PREFIX) echo " [LD] ast_expr2fz.o ast_expr2z.o -> check_expr2"
$(CC) -g -o check_expr2 ast_expr2fz.o ast_expr2z.o astmm.o -lm $(_ASTLDFLAGS)
$(ECHO_PREFIX) echo " [RM] ast_expr2fz.o ast_expr2z.o"
rm ast_expr2z.o ast_expr2fz.o
- ./check_expr2 expr2.testinput
smsq: smsq.o strcompat.o
smsq: LIBS+=$(POPT_LIB)

View file

@ -17,12 +17,12 @@
* build.h
--- a/Makefile
+++ b/Makefile
@@ -484,7 +484,7 @@ doc/core-en_US.xml: makeopts .lastclean
@@ -489,7 +489,7 @@ doc/core-en_US.xml: makeopts .lastclean
@echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@
@for x in $(MOD_SUBDIRS); do \
printf "$$x " ; \
- for i in `find $$x -name '*.c'`; do \
+ for i in `find $$x -name '*.c' | LC_ALL=C sort`; do \
$(AWK) -f build_tools/get_documentation $$i >> $@ ; \
done ; \
done
MODULEINFO=$$($(AWK) -f build_tools/get_moduleinfo $$i) ; \
if [ -n "$$MODULEINFO" ] ; \
then \

View file

@ -1,247 +0,0 @@
commit 02fda2b478f98cf3b8a1df76f772bf0be73bddd5
Author: Sebastian Kemper <sebastian_ml@gmx.net>
Date: Tue Apr 2 22:49:52 2019 +0200
loader: support for permanent dlopen()
Asterisk assumes that dlopen() will always run the constructor of a
shared library and every dlclose() will run its destructor. But dlopen()
may be permanent, meaning the constructor will only be run once, as is
the case with musl libc.
With a permanent dlopen() the Asterisk module loader does not work
correctly, because it's expectations regarding when the constructors and
destructors are run are not met. In fact a segmentation fault will occur
when the first module is "re-opened" that has AST_MODFLAG_GLOBAL_SYMBOLS
set (the dlopen() does not call the constructor, resource_being_loaded
is not set to NULL, then strlen is called with NULL instead of a string,
see issue ASTERISK-28319).
This commit adds code to the loader that will manually run the
constructors/destructors of the (non-builtin) modules where needed. To
achieve this a new ao2 container (linked list) is started and filled
with objects that contain the names of the modules and the pointers to
their respective info structs.
This behavior can be activated when configuring Asterisk
(--enable-permanent-dlopen). By default this is disabled, of course.
ASTERISK-28319 #close
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Change-Id: I86693a0ecf25d5ba81c73773a03df4abc3426875
--- a/configure.ac
+++ b/configure.ac
@@ -727,6 +727,20 @@ if test "${DISABLE_XMLDOC}" != "yes"; th
fi
+AC_ARG_ENABLE([permanent-dlopen],
+ [AS_HELP_STRING([--enable-permanent-dlopen],
+ [Enable when your libc has a permanent dlopen like musl])],
+ [case "${enableval}" in
+ y|ye|yes) PERMANENT_DLOPEN=yes ;;
+ n|no) PERMANENT_DLOPEN=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-permanent-dlopen) ;;
+ esac], [PERMANENT_DLOPEN=no])
+
+AC_SUBST([PERMANENT_DLOPEN])
+if test "${PERMANENT_DLOPEN}" == "yes"; then
+ AC_DEFINE([HAVE_PERMANENT_DLOPEN], 1, [Define to support libc with permanent dlopen.])
+fi
+
# some embedded systems omit internationalization (locale) support
AC_CHECK_HEADERS([xlocale.h])
--- a/main/loader.c
+++ b/main/loader.c
@@ -153,6 +153,117 @@ static unsigned int loader_ready;
static struct ast_vector_string startup_errors;
static struct ast_str *startup_error_builder;
+#if defined(HAVE_PERMANENT_DLOPEN)
+#define FIRST_DLOPEN 999
+
+struct ao2_container *info_list = NULL;
+
+struct info_list_obj {
+ const struct ast_module_info *info;
+ int dlopened;
+ char name[0];
+};
+
+static struct info_list_obj *info_list_obj_alloc(const char *name,
+ const struct ast_module_info *info)
+{
+ struct info_list_obj *new_entry;
+
+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
+
+ if (!new_entry) {
+ return NULL;
+ }
+
+ strcpy(new_entry->name, name); /* SAFE */
+ new_entry->info = info;
+ new_entry->dlopened = FIRST_DLOPEN;
+
+ return new_entry;
+}
+
+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
+
+static char *get_name_from_resource(const char *resource)
+{
+ int len;
+ const char *last_three;
+ char *mod_name;
+
+ if (!resource) {
+ return NULL;
+ }
+
+ len = strlen(resource);
+ if (len > 3) {
+ last_three = &resource[len-3];
+ if (!strcasecmp(last_three, ".so")) {
+ mod_name = ast_calloc(1, len - 2);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len - 2);
+ return mod_name;
+ } else {
+ /* Unable to allocate memory. */
+ return NULL;
+ }
+ }
+ }
+
+ /* Resource is the name - happens when manually unloading a module. */
+ mod_name = ast_calloc(1, len + 1);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len + 1);
+ return mod_name;
+ }
+
+ /* Unable to allocate memory. */
+ return NULL;
+}
+
+static void manual_mod_reg(const void *lib, const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ if (lib) {
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ if (obj_tmp->dlopened == FIRST_DLOPEN) {
+ obj_tmp->dlopened = 1;
+ } else {
+ ast_module_register(obj_tmp->info);
+ }
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+ }
+}
+
+static void manual_mod_unreg(const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ /* When Asterisk shuts down the destructor is called automatically. */
+ if (ast_shutdown_final()) {
+ return;
+ }
+
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ ast_module_unregister(obj_tmp->info);
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+}
+#endif
+
static __attribute__((format(printf, 1, 2))) void module_load_error(const char *fmt, ...)
{
char *copy = NULL;
@@ -597,6 +708,23 @@ void ast_module_register(const struct as
/* give the module a copy of its own handle, for later use in registrations and the like */
*((struct ast_module **) &(info->self)) = mod;
+
+#if defined(HAVE_PERMANENT_DLOPEN)
+ if (mod->flags.builtin != 1) {
+ struct info_list_obj *obj_tmp = ao2_find(info_list, info->name,
+ OBJ_SEARCH_KEY);
+
+ if (!obj_tmp) {
+ obj_tmp = info_list_obj_alloc(info->name, info);
+ if (obj_tmp) {
+ ao2_link(info_list, obj_tmp);
+ ao2_ref(obj_tmp, -1);
+ }
+ } else {
+ ao2_ref(obj_tmp, -1);
+ }
+ }
+#endif
}
static int module_post_register(struct ast_module *mod)
@@ -843,6 +971,10 @@ static void logged_dlclose(const char *n
error = dlerror();
ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
S_OR(name, "unknown"), S_OR(error, "Unknown error"));
+#if defined(HAVE_PERMANENT_DLOPEN)
+ } else {
+ manual_mod_unreg(name);
+#endif
}
}
@@ -949,6 +1081,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, flags);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
struct ast_str *list;
int c = 0;
@@ -968,6 +1103,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
resource_being_loaded = NULL;
@@ -2206,6 +2344,15 @@ int load_modules(void)
ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
+#if defined(HAVE_PERMANENT_DLOPEN)
+ info_list = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL,
+ info_list_obj_cmp_fn); /* must not be cleaned at shutdown */
+ if (!info_list) {
+ fprintf(stderr, "Module info list allocation failure.\n");
+ return 1;
+ }
+#endif
+
AST_LIST_HEAD_INIT_NOLOCK(&load_order);
AST_DLLIST_LOCK(&module_list);

View file

@ -1,6 +1,6 @@
--- a/configure.ac
+++ b/configure.ac
@@ -1205,7 +1205,7 @@ if test "${ac_cv_have_variable_fdset}x"
@@ -1206,7 +1206,7 @@ if test "${ac_cv_have_variable_fdset}x"
fi
AC_MSG_CHECKING([if we have usable eventfd support])

View file

@ -1,40 +0,0 @@
From 785bf3a755e47d92caef110e6040295764d08127 Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@digium.com>
Date: Wed, 12 Jun 2019 12:03:04 -0600
Subject: [PATCH] res_pjsip_messaging: Check for body in in-dialog message
We now check that a body exists and it has a length > 0 before
attempting to process it.
ASTERISK-28447
Reported-by: Gil Richard
Change-Id: Ic469544b22ab848734636588d4c93426cc6f4b1f
---
res/res_pjsip_messaging.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c
index 0e10a8f047..930cf84a53 100644
--- a/res/res_pjsip_messaging.c
+++ b/res/res_pjsip_messaging.c
@@ -90,10 +90,13 @@ static enum pjsip_status_code check_content_type_in_dialog(const pjsip_rx_data *
static const pj_str_t text = { "text", 4};
static const pj_str_t application = { "application", 11};
+ if (!(rdata->msg_info.msg->body && rdata->msg_info.msg->body->len > 0)) {
+ return res;
+ }
+
/* We'll accept any text/ or application/ content type */
- if (rdata->msg_info.msg->body && rdata->msg_info.msg->body->len
- && (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0
- || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0)) {
+ if (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0
+ || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0) {
res = PJSIP_SC_OK;
} else if (rdata->msg_info.ctype
&& (pj_stricmp(&rdata->msg_info.ctype->media.type, &text) == 0
--
2.21.0

View file

@ -1,39 +0,0 @@
From 1e4df0215af4f192ed06a7fc7589c799f1ec6091 Mon Sep 17 00:00:00 2001
From: Francesco Castellano <francesco.castellano@messagenet.it>
Date: Fri, 28 Jun 2019 18:15:31 +0200
Subject: [PATCH] chan_sip: Handle invalid SDP answer to T.38 re-invite
The chan_sip module performs a T.38 re-invite using a single media
stream of udptl, and expects the SDP answer to be the same.
If an SDP answer is received instead that contains an additional
media stream with no joint codec a crash will occur as the code
assumes that at least one joint codec will exist in this
scenario.
This change removes this assumption.
ASTERISK-28465
Change-Id: I8b02845b53344c6babe867a3f0a5231045c7ac87
---
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 898b646..a609ff8 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -10965,7 +10965,13 @@
ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0));
}
- if (portno != -1 || vportno != -1 || tportno != -1) {
+ /* When UDPTL is negotiated it is expected that there are no compatible codecs as audio or
+ * video is not being transported, thus we continue in this function further up if that is
+ * the case. If we receive an SDP answer containing both a UDPTL stream and another media
+ * stream however we need to check again to ensure that there is at least one joint codec
+ * instead of assuming there is one.
+ */
+ if ((portno != -1 || vportno != -1 || tportno != -1) && ast_format_cap_count(newjointcapability)) {
/* We are now ready to change the sip session and RTP structures with the offered codecs, since
they are acceptable */
unsigned int framing;

View file

@ -1,171 +0,0 @@
From 69ed619a6d9b64a297d3099b6455756912e21d0b Mon Sep 17 00:00:00 2001
From: Kevin Harwell <kharwell@digium.com>
Date: Tue, 20 Aug 2019 15:05:45 -0500
Subject: [PATCH] AST-2019-004 - res_pjsip_t38.c: Add NULL checks before using session media
After receiving a 200 OK with a declined stream in response to a T.38
initiated re-invite Asterisk would crash when attempting to dereference
a NULL session media object.
This patch checks to make sure the session media object is not NULL before
attempting to use it.
ASTERISK-28495
patches:
ast-2019-004.patch submitted by Alexei Gradinari (license 5691)
Change-Id: I168f45f4da29cfe739acf87e597baa2aae7aa572
---
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 11804e2..e5c6090 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -203,7 +203,6 @@
{
RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup);
RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
- struct ast_sip_session_media *session_media;
if (!datastore) {
return 0;
@@ -212,8 +211,7 @@
ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n",
session->channel ? ast_channel_name(session->channel) : "<gone>");
- session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, datastore->data, T38_REJECTED);
+ t38_change_state(session, NULL, datastore->data, T38_REJECTED);
ast_sip_session_resume_reinvite(session);
return 0;
@@ -322,28 +320,37 @@
int index;
session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, state, T38_ENABLED);
+ if (!session_media) {
+ ast_log(LOG_WARNING, "Received %d response to T.38 re-invite on '%s' but no active session media\n",
+ status.code, session->channel ? ast_channel_name(session->channel) : "unknown channel");
+ } else {
+ t38_change_state(session, session_media, state, T38_ENABLED);
- /* Stop all the streams in the stored away active state, they'll go back to being active once
- * we reinvite back.
- */
- for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) {
- struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index);
+ /* Stop all the streams in the stored away active state, they'll go back to being active once
+ * we reinvite back.
+ */
+ for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) {
+ struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index);
- if (session_media && session_media->handler && session_media->handler->stream_stop) {
- session_media->handler->stream_stop(session_media);
+ if (session_media && session_media->handler && session_media->handler->stream_stop) {
+ session_media->handler->stream_stop(session_media);
+ }
}
+
+ return 0;
}
} else {
session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(session, session_media, state, T38_REJECTED);
-
- /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */
- ast_sip_session_media_state_free(state->media_state);
- state->media_state = NULL;
- ast_sip_session_media_state_reset(session->pending_media_state);
}
+ /* If no session_media then response contained a declined stream, so disable */
+ t38_change_state(session, NULL, state, session_media ? T38_REJECTED : T38_DISABLED);
+
+ /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */
+ ast_sip_session_media_state_free(state->media_state);
+ state->media_state = NULL;
+ ast_sip_session_media_state_reset(session->pending_media_state);
+
return 0;
}
@@ -426,12 +433,10 @@
/* Negotiation can not take place without a valid max_ifp value. */
if (!parameters->max_ifp) {
if (data->session->t38state == T38_PEER_REINVITE) {
- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_REJECTED);
+ t38_change_state(data->session, NULL, state, T38_REJECTED);
ast_sip_session_resume_reinvite(data->session);
} else if (data->session->t38state == T38_ENABLED) {
- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_DISABLED);
+ t38_change_state(data->session, NULL, state, T38_DISABLED);
ast_sip_session_refresh(data->session, NULL, NULL, NULL,
AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state);
state->media_state = NULL;
@@ -454,6 +459,11 @@
state->our_parms.version = MIN(state->our_parms.version, state->their_parms.version);
state->our_parms.rate_management = state->their_parms.rate_management;
session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to negotiate parameters for reinvite on channel '%s' (No pending session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
t38_change_state(data->session, session_media, state, T38_ENABLED);
ast_sip_session_resume_reinvite(data->session);
@@ -468,8 +478,13 @@
}
state->our_parms = *parameters;
session_media = media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to negotiate parameters on channel '%s' (No default session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
- t38_change_state(data->session, session_media, state, T38_LOCAL_REINVITE);
+ t38_change_state(data->session, NULL, state, T38_LOCAL_REINVITE);
ast_sip_session_refresh(data->session, NULL, t38_reinvite_sdp_cb, t38_reinvite_response_cb,
AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, media_state);
}
@@ -478,12 +493,10 @@
case AST_T38_REFUSED:
case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */
if (data->session->t38state == T38_PEER_REINVITE) {
- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_REJECTED);
+ t38_change_state(data->session, NULL, state, T38_REJECTED);
ast_sip_session_resume_reinvite(data->session);
} else if (data->session->t38state == T38_ENABLED) {
- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
- t38_change_state(data->session, session_media, state, T38_DISABLED);
+ t38_change_state(data->session, NULL, state, T38_DISABLED);
ast_sip_session_refresh(data->session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state);
state->media_state = NULL;
}
@@ -493,6 +506,11 @@
if (data->session->t38state == T38_PEER_REINVITE) {
session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+ if (!session_media) {
+ ast_log(LOG_ERROR, "Failed to request parameters for reinvite on channel '%s' (No pending session media).\n",
+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel");
+ break;
+ }
parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
ast_queue_control_data(data->session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
@@ -788,7 +806,7 @@
if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) {
ast_debug(3, "Declining; T.38 state is rejected or declined\n");
- t38_change_state(session, session_media, state, T38_DISABLED);
+ t38_change_state(session, NULL, state, T38_DISABLED);
return 0;
}

View file

@ -1,73 +0,0 @@
From 8cdaa93e658a46e7baf6b606468b5e2c88a0133b Mon Sep 17 00:00:00 2001
From: Ben Ford <bford@digium.com>
Date: Mon, 21 Oct 2019 14:55:06 -0500
Subject: [PATCH] chan_sip.c: Prevent address change on unauthenticated SIP request.
If the name of a peer is known and a SIP request is sent using that
peer's name, the address of the peer will change even if the request
fails the authentication challenge. This means that an endpoint can
be altered and even rendered unusuable, even if it was in a working
state previously. This can only occur when the nat option is set to the
default, or auto_force_rport.
This change checks the result of authentication first to ensure it is
successful before setting the address and the nat option.
ASTERISK-28589 #close
Change-Id: I581c5ed1da60ca89f590bd70872de2b660de02df
---
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 6ac2e61..4d79a47 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -19245,18 +19245,6 @@
bogus_peer = NULL;
}
- /* build_peer, called through sip_find_peer, is not able to check the
- * sip_pvt->natdetected flag in order to determine if the peer is behind
- * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
- * are set on the peer. So we check for that here and set the peer's
- * address accordingly.
- */
- set_peer_nat(p, peer);
-
- if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
- ast_sockaddr_copy(&peer->addr, &p->recv);
- }
-
if (!ast_apply_acl(peer->acl, addr, "SIP Peer ACL: ")) {
ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
@@ -19325,6 +19313,21 @@
ast_string_field_set(p, peermd5secret, NULL);
}
if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable))) {
+
+ /* build_peer, called through sip_find_peer, is not able to check the
+ * sip_pvt->natdetected flag in order to determine if the peer is behind
+ * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
+ * are set on the peer. So we check for that here and set the peer's
+ * address accordingly. The address should ONLY be set once we are sure
+ * authentication was a success. If, for example, an INVITE was sent that
+ * matched the peer name but failed the authentication check, the address
+ * would be updated, which is bad.
+ */
+ set_peer_nat(p, peer);
+ if (p->natdetected && ast_test_flag(&peer->flags[2], SIP_PAGE3_NAT_AUTO_RPORT)) {
+ ast_sockaddr_copy(&peer->addr, &p->recv);
+ }
+
/* If we have a call limit, set flag */
if (peer->call_limit)
ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
@@ -19424,6 +19427,7 @@
}
}
sip_unref_peer(peer, "check_peer_ok: sip_unref_peer: tossing temp ptr to peer from sip_find_peer");
+
return res;
}

View file

@ -1,41 +0,0 @@
From 7574be5110e049a44b8c8ead52cd1c2a5d442afa Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@digium.com>
Date: Thu, 24 Oct 2019 11:41:23 -0600
Subject: [PATCH] manager.c: Prevent the Originate action from running the Originate app
If an AMI user without the "system" authorization calls the
Originate AMI command with the Originate application,
the second Originate could run the "System" command.
Action: Originate
Channel: Local/1111
Application: Originate
Data: Local/2222,app,System,touch /tmp/owned
If the "system" authorization isn't set, we now block the
Originate app as well as the System, Exec, etc. apps.
ASTERISK-28580
Reported by: Eliel Sardañons
Change-Id: Ic4c9dedc34c426f03c8c14fce334a71386d8a5fa
---
--- /dev/null
+++ b/doc/UPGRADE-staging/AMI-Originate.txt
@@ -0,0 +1,5 @@
+Subject: AMI
+
+The AMI Originate action, which optionally takes a dialplan application as
+an argument, no longer accepts "Originate" as the application due to
+security concerns.
--- a/main/manager.c
+++ b/main/manager.c
@@ -5697,6 +5697,7 @@ static int action_originate(struct manse
EAGI(/bin/rm,-rf /) */
strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
+ strcasestr(app, "originate") || /* Originate(Local/1234,app,System,rm -rf) */
(strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
(strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {

View file

@ -1,401 +0,0 @@
commit 523ed150b16d799bcf223b841abd82f25b8cd6a0
Author: Kevin Harwell <kharwell@digium.com>
Date: Mon Oct 19 17:21:57 2020 -0500
AST-2020-001 - res_pjsip: Return dialog locked and referenced
pjproject returns the dialog locked and with a reference. However,
in Asterisk the method that handles this decrements the reference
and removes the lock prior to returning. This makes it possible,
under some circumstances, for another thread to free said dialog
before the thread that created it attempts to use it again. Of
course when the thread that created it tries to use a freed dialog
a crash can occur.
This patch makes it so Asterisk now returns the newly created
dialog both locked, and with an added reference. This allows the
caller to de-reference, and unlock the dialog when it is safe to
do so.
In the case of a new SIP Invite the lock, and reference are now
held for the entirety of the new invite handling process.
Otherwise it's possible for the dialog, or its dependent objects,
like the transaction, to disappear. For example if there is a TCP
transport error.
Change-Id: I5ef645a47829596f402cf383dc02c629c618969e
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -1908,6 +1908,11 @@ pjsip_dialog *ast_sip_create_dialog_uac(
/*!
* \brief General purpose method for creating a UAS dialog with an endpoint
*
+ * \deprecated This function is unsafe (due to the returned object not being locked nor
+ * having its reference incremented) and should no longer be used. Instead
+ * use ast_sip_create_dialog_uas_locked so a properly locked and referenced
+ * object is returned.
+ *
* \param endpoint A pointer to the endpoint
* \param rdata The request that is starting the dialog
* \param[out] status On failure, the reason for failure in creating the dialog
@@ -1915,6 +1920,44 @@ pjsip_dialog *ast_sip_create_dialog_uac(
pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status);
/*!
+ * \brief General purpose method for creating a UAS dialog with an endpoint
+ *
+ * This function creates and returns a locked, and referenced counted pjsip
+ * dialog object. The caller is thus responsible for freeing the allocated
+ * memory, decrementing the reference, and releasing the lock when done with
+ * the returned object.
+ *
+ * \note The safest way to unlock the object, and decrement its reference is by
+ * calling pjsip_dlg_dec_lock. Alternatively, pjsip_dlg_dec_session can be
+ * used to decrement the reference only.
+ *
+ * The dialog is returned locked and with a reference in order to ensure that the
+ * dialog object, and any of its associated objects (e.g. transaction) are not
+ * untimely destroyed. For instance, that could happen when a transport error
+ * occurs.
+ *
+ * As long as the caller maintains a reference to the dialog there should be no
+ * worry that it might unknowningly be destroyed. However, once the caller unlocks
+ * the dialog there is a danger that some of the dialog's internal objects could
+ * be lost and/or compromised. For example, when the aforementioned transport error
+ * occurs the dialog's associated transaction gets destroyed (see pjsip_dlg_on_tsx_state
+ * in sip_dialog.c, and mod_inv_on_tsx_state in sip_inv.c).
+ *
+ * In this case and before using the dialog again the caller should re-lock the
+ * dialog, check to make sure the dialog is still established, and the transaction
+ * still exists and has not been destroyed.
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param rdata The request that is starting the dialog
+ * \param[out] status On failure, the reason for failure in creating the dialog
+ *
+ * \retval A locked, and reference counted pjsip_dialog object.
+ * \retval NULL on failure
+ */
+pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status);
+
+/*!
* \brief General purpose method for creating an rdata structure using specific information
* \since 13.15.0
*
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3645,7 +3645,11 @@ static int uas_use_sips_contact(pjsip_rx
return 0;
}
-pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
+typedef pj_status_t (*create_dlg_uac)(pjsip_user_agent *ua, pjsip_rx_data *rdata,
+ const pj_str_t *contact, pjsip_dialog **p_dlg);
+
+static pjsip_dialog *create_dialog_uas(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
{
pjsip_dialog *dlg;
pj_str_t contact;
@@ -3680,11 +3684,7 @@ pjsip_dialog *ast_sip_create_dialog_uas(
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
-#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
- *status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact, &dlg);
-#else
- *status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
-#endif
+ *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
if (*status != PJ_SUCCESS) {
char err[PJ_ERR_MSG_SIZE];
@@ -3697,11 +3697,46 @@ pjsip_dialog *ast_sip_create_dialog_uas(
dlg->sess_count++;
pjsip_dlg_set_transport(dlg, &selector);
dlg->sess_count--;
+
+ return dlg;
+}
+
+pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
+{
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
- pjsip_dlg_dec_lock(dlg);
+ pjsip_dialog *dlg;
+
+ dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
+ if (dlg) {
+ pjsip_dlg_dec_lock(dlg);
+ }
+
+ return dlg;
+#else
+ return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
#endif
+}
+
+pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
+ pjsip_rx_data *rdata, pj_status_t *status)
+{
+#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
+ return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
+#else
+ /*
+ * This is put here in order to be compatible with older versions of pjproject.
+ * Best we can do in this case is immediately lock after getting the dialog.
+ * However, that does leave a "gap" between creating and locking.
+ */
+ pjsip_dialog *dlg;
+
+ dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
+ if (dlg) {
+ pjsip_dlg_inc_lock(dlg);
+ }
return dlg;
+#endif
}
int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port,
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -1457,7 +1457,7 @@ static struct sip_subscription_tree *cre
}
sub_tree->role = AST_SIP_NOTIFIER;
- dlg = ast_sip_create_dialog_uas(endpoint, rdata, dlg_status);
+ dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, dlg_status);
if (!dlg) {
if (*dlg_status != PJ_EEXISTS) {
ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
@@ -1478,8 +1478,16 @@ static struct sip_subscription_tree *cre
}
pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &sub_tree->evsub);
+
subscription_setup_dialog(sub_tree, dlg);
+ /*
+ * The evsub and subscription setup both add dialog refs, so the dialog ref that
+ * was added when the dialog was created (see ast_sip_create_dialog_uas_lock) can
+ * now be removed. The lock should no longer be needed so can be removed too.
+ */
+ pjsip_dlg_dec_lock(dlg);
+
#ifdef HAVE_PJSIP_EVSUB_GRP_LOCK
pjsip_evsub_add_ref(sub_tree->evsub);
#endif
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2942,6 +2942,75 @@ static enum sip_get_destination_result g
return SIP_GET_DEST_EXTEN_NOT_FOUND;
}
+/*
+ * /internal
+ * /brief Process initial answer for an incoming invite
+ *
+ * This function should only be called during the setup, and handling of a
+ * new incoming invite. Most, if not all of the time, this will be called
+ * when an error occurs and we need to respond as such.
+ *
+ * When a SIP session termination code is given for the answer it's assumed
+ * this call then will be the final bit of processing before ending session
+ * setup. As such, we've been holding a lock, and a reference on the invite
+ * session's dialog. So before returning this function removes that reference,
+ * and unlocks the dialog.
+ *
+ * \param inv_session The session on which to answer
+ * \param rdata The original request
+ * \param answer_code The answer's numeric code
+ * \param terminate_code The termination code if the answer fails
+ * \param notify Whether or not to call on_state_changed
+ *
+ * \retval 0 if invite successfully answered, -1 if an error occurred
+ */
+static int new_invite_initial_answer(pjsip_inv_session *inv_session, pjsip_rx_data *rdata,
+ int answer_code, int terminate_code, pj_bool_t notify)
+{
+ pjsip_tx_data *tdata = NULL;
+ int res = 0;
+
+ if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
+ if (pjsip_inv_initial_answer(
+ inv_session, rdata, answer_code, NULL, NULL, &tdata) != PJ_SUCCESS) {
+
+ pjsip_inv_terminate(inv_session, terminate_code ? terminate_code : answer_code, notify);
+ res = -1;
+ } else {
+ pjsip_inv_send_msg(inv_session, tdata);
+ }
+ }
+
+ if (answer_code >= 300) {
+ /*
+ * A session is ending. The dialog has a reference that needs to be
+ * removed and holds a lock that needs to be unlocked before returning.
+ */
+ pjsip_dlg_dec_lock(inv_session->dlg);
+ }
+
+ return res;
+}
+
+/*
+ * /internal
+ * /brief Create and initialize a pjsip invite session
+
+ * pjsip_inv_session adds, and maintains a reference to the dialog upon a successful
+ * invite session creation until the session is destroyed. However, we'll wait to
+ * remove the reference that was added for the dialog when it gets created since we're
+ * not ready to unlock the dialog in this function.
+ *
+ * So, if this function successfully returns that means it returns with its newly
+ * created, and associated dialog locked and with two references (i.e. dialog's
+ * reference count should be 2).
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param rdata The request that is starting the dialog
+ *
+ * \retval A pjsip invite session object
+ * \retval NULL on error
+ */
static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct ast_sip_endpoint *endpoint)
{
pjsip_tx_data *tdata;
@@ -2960,15 +3029,28 @@ static pjsip_inv_session *pre_session_se
}
return NULL;
}
- dlg = ast_sip_create_dialog_uas(endpoint, rdata, &dlg_status);
+
+ dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, &dlg_status);
if (!dlg) {
if (dlg_status != PJ_EEXISTS) {
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
}
return NULL;
}
+
+ /*
+ * The returned dialog holds a lock and has a reference added. Any paths where the
+ * dialog invite session is not returned must unlock the dialog and remove its reference.
+ */
+
if (pjsip_inv_create_uas(dlg, rdata, NULL, options, &inv_session) != PJ_SUCCESS) {
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+ /*
+ * The acquired dialog holds a lock, and a reference. Since the dialog is not
+ * going to be returned here it must first be unlocked and de-referenced. This
+ * must be done prior to calling dialog termination.
+ */
+ pjsip_dlg_dec_lock(dlg);
pjsip_dlg_terminate(dlg);
return NULL;
}
@@ -2977,12 +3059,13 @@ static pjsip_inv_session *pre_session_se
inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
#endif
if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) != PJ_SUCCESS) {
- pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- }
- pjsip_inv_send_msg(inv_session, tdata);
+ /* Dialog's lock and a reference are removed in new_invite_initial_answer */
+ new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE);
+ /* Remove 2nd reference added at inv_session creation */
+ pjsip_dlg_dec_session(inv_session->dlg, &session_module);
return NULL;
}
+
return inv_session;
}
@@ -3121,7 +3204,6 @@ static void handle_new_invite_request(pj
{
RAII_VAR(struct ast_sip_endpoint *, endpoint,
ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
- pjsip_tx_data *tdata = NULL;
pjsip_inv_session *inv_session = NULL;
struct ast_sip_session *session;
struct new_invite invite;
@@ -3134,27 +3216,48 @@ static void handle_new_invite_request(pj
return;
}
+ /*
+ * Upon a successful pre_session_setup the associated dialog is returned locked
+ * and with an added reference. Well actually two references. One added when the
+ * dialog itself was created, and another added when the pjsip invite session was
+ * created and the dialog was added to it.
+ *
+ * In order to ensure the dialog's, and any of its internal attributes, lifetimes
+ * we'll hold the lock and maintain the reference throughout the entire new invite
+ * handling process. See ast_sip_create_dialog_uas_locked for more details but,
+ * basically we do this to make sure a transport failure does not destroy the dialog
+ * and/or transaction out from underneath us between pjsip calls. Alternatively, we
+ * could probably release the lock if we needed to, but then we'd have to re-lock and
+ * check the dialog and transaction prior to every pjsip call.
+ *
+ * That means any off nominal/failure paths in this function must remove the associated
+ * dialog reference added at dialog creation, and remove the lock. As well the
+ * referenced pjsip invite session must be "cleaned up", which should also then
+ * remove its reference to the dialog at that time.
+ *
+ * Nominally we'll unlock the dialog, and release the reference when all new invite
+ * process handling has successfully completed.
+ */
+
#ifdef HAVE_PJSIP_INV_SESSION_REF
if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
- pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- } else {
- pjsip_inv_send_msg(inv_session, tdata);
- }
+ /* Dialog's lock and a reference are removed in new_invite_initial_answer */
+ if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
+ /* Terminate the session if it wasn't done in the answer */
+ pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
}
return;
}
#endif
-
session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
if (!session) {
- if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
+ /* Dialog's lock and reference are removed in new_invite_initial_answer */
+ if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
+ /* Terminate the session if it wasn't done in the answer */
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- } else {
- pjsip_inv_send_msg(inv_session, tdata);
}
+
#ifdef HAVE_PJSIP_INV_SESSION_REF
pjsip_inv_dec_ref(inv_session);
#endif
@@ -3172,6 +3275,17 @@ static void handle_new_invite_request(pj
invite.rdata = rdata;
new_invite(&invite);
+ /*
+ * The dialog lock and reference added at dialog creation time must be
+ * maintained throughout the new invite process. Since we're pretty much
+ * done at this point with things it's safe to go ahead and remove the lock
+ * and the reference here. See ast_sip_create_dialog_uas_locked for more info.
+ *
+ * Note, any future functionality added that does work using the dialog must
+ * be done before this.
+ */
+ pjsip_dlg_dec_lock(inv_session->dlg);
+
ao2_ref(session, -1);
}

View file

@ -1,102 +0,0 @@
From f83efa12f7411dd100f49933bf71297c8ed9f765 Mon Sep 17 00:00:00 2001
From: Ben Ford <bford@digium.com>
Date: Mon, 02 Nov 2020 10:29:31 -0600
Subject: [PATCH] AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit.
If Asterisk sends out an INVITE and receives a challenge with a
different nonce value each time, it will continuously send out INVITEs,
even if the call is hung up. The endpoint must be configured for
outbound authentication for this to occur. A limit has been set on
outbound INVITEs so that, once reached, Asterisk will stop sending
INVITEs and the transaction will terminate.
ASTERISK-29013
Change-Id: I2d001ca745b00ca8aa12030f2240cd72363b46f7
---
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -63,6 +63,9 @@ struct pjsip_tpselector;
/*! \brief Maximum number of ciphers supported for a TLS transport */
#define SIP_TLS_MAX_CIPHERS 64
+/*! Maximum number of challenges before assuming that we are in a loop */
+#define MAX_RX_CHALLENGES 10
+
/*!
* \brief Structure for SIP transport information
*/
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -215,8 +215,10 @@ struct ast_sip_session {
enum ast_sip_dtmf_mode dtmf;
/*! Initial incoming INVITE Request-URI. NULL otherwise. */
pjsip_uri *request_uri;
- /* Media statistics for negotiated RTP streams */
+ /*! Media statistics for negotiated RTP streams */
AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats;
+ /*! Number of challenges received during outgoing requests to determine if we are in a loop */
+ unsigned int authentication_challenge_count:4;
};
typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -4027,8 +4027,6 @@ static pj_bool_t does_method_match(const
return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
}
-/*! Maximum number of challenges before assuming that we are in a loop */
-#define MAX_RX_CHALLENGES 10
#define TIMER_INACTIVE 0
#define TIMEOUT_TIMER2 5
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2052,7 +2052,6 @@ static pjsip_module session_reinvite_mod
.on_rx_request = session_reinvite_on_rx_request,
};
-
void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
ast_sip_session_response_cb on_response)
{
@@ -2301,6 +2300,9 @@ struct ast_sip_session *ast_sip_session_
return NULL;
}
+ /* Track the number of challenges received on outbound requests */
+ session->authentication_challenge_count = 0;
+
/* Fire seesion begin handlers */
handle_session_begin(session);
@@ -2470,6 +2472,11 @@ static pj_bool_t outbound_invite_auth(pj
session = inv->mod_data[session_module.id];
+ if (++session->authentication_challenge_count > MAX_RX_CHALLENGES) {
+ ast_debug(1, "Initial INVITE reached maximum number of auth attempts.\n");
+ return PJ_FALSE;
+ }
+
if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata,
tsx->last_tx, &tdata)) {
return PJ_FALSE;
@@ -3846,6 +3853,7 @@ static void session_inv_on_tsx_state_cha
ast_debug(1, "reINVITE received final response code %d\n",
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
+ && ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {
@@ -3920,6 +3928,7 @@ static void session_inv_on_tsx_state_cha
(int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
+ && ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {

View file

@ -1,87 +0,0 @@
From 757b7f8d7cfee4f541e8d7586e2408556a74201d Mon Sep 17 00:00:00 2001
From: Ivan Poddubnyi <ivan.poddubny@gmail.com>
Date: Mon, 28 Dec 2020 13:43:23 +0100
Subject: [PATCH] res_pjsip_diversion: Fix adding more than one histinfo to
Supported
New responses sent within a PJSIP sessions are based on those that were
sent before. Therefore, adding/modifying a header once causes it to be
sent on all responses that follow.
Sending 181 Call Is Being Forwarded many times first adds "histinfo"
duplicated more and more, and eventually overflows past the array
boundary.
This commit adds a check preventing adding "histinfo" more than once,
and skipping it if there is no more space in the header.
Similar overflow situations can also occur in res_pjsip_path and
res_pjsip_outbound_registration so those were also modified to
check the bounds and suppress duplicate Supported values.
ASTERISK-29227
Reported by: Ivan Poddubny
Change-Id: Id43704a1f1a0293e35cc7f844026f0b04f2ac322
---
res/res_pjsip_diversion.c | 14 ++++++++++++++
res/res_pjsip_outbound_registration.c | 12 ++++++++++++
res/res_pjsip_path.c | 12 ++++++++++++
3 files changed, 38 insertions(+)
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -580,6 +580,7 @@ static int handle_client_registration(vo
if (client_state->support_path) {
pjsip_supported_hdr *hdr;
+ int i;
hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
if (!hdr) {
@@ -593,6 +594,17 @@ static int handle_client_registration(vo
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
}
+ /* Don't add the value if it's already there */
+ for (i = 0; i < hdr->count; ++i) {
+ if (pj_stricmp(&hdr->values[i], &PATH_NAME) == 0) {
+ return 1;
+ }
+ }
+
+ if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+ return 0;
+ }
+
/* add on to the existing Supported header */
pj_strassign(&hdr->values[hdr->count++], &PATH_NAME);
}
--- a/res/res_pjsip_path.c
+++ b/res/res_pjsip_path.c
@@ -122,6 +122,7 @@ static int path_get_string(pj_pool_t *po
static int add_supported(pjsip_tx_data *tdata)
{
pjsip_supported_hdr *hdr;
+ int i;
hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
if (!hdr) {
@@ -134,6 +135,17 @@ static int add_supported(pjsip_tx_data *
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
}
+ /* Don't add the value if it's already there */
+ for (i = 0; i < hdr->count; ++i) {
+ if (pj_stricmp(&hdr->values[i], &PATH_SUPPORTED_NAME) == 0) {
+ return 0;
+ }
+ }
+
+ if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+ return -1;
+ }
+
/* add on to the existing Supported header */
pj_strassign(&hdr->values[hdr->count++], &PATH_SUPPORTED_NAME);