[Git][pkg-voip-team/asterisk][master] 3 commits: AST-2021-008 / CVE-2021-32558: Remote crash when using IAX2 channel driver

Bernhard Schmidt (@berni) gitlab at salsa.debian.org
Mon Nov 1 21:28:41 GMT 2021



Bernhard Schmidt pushed to branch master at Debian VoIP Packaging Team / asterisk


Commits:
6dd60d12 by Bernhard Schmidt at 2021-08-06T15:33:03+02:00
AST-2021-008 / CVE-2021-32558: Remote crash when using IAX2 channel driver

Closes: #991710

- - - - -
e9f1dc41 by Bernhard Schmidt at 2021-08-06T15:34:45+02:00
AST-2021-009 / CVE-2021-32686: pjproject/pjsip: crash when SSL socket destroyed during handshake

Closes: #991931

- - - - -
c355df4f by Bernhard Schmidt at 2021-08-06T15:37:22+02:00
Changelog for 1:16.16.1~dfsg-2

- - - - -


4 changed files:

- debian/changelog
- + debian/patches/AST-2021-008-16.diff
- + debian/patches/AST-2021-009-16.diff
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+asterisk (1:16.16.1~dfsg-2) unstable; urgency=high
+
+  * CVE-2021-32558 / AST-2021-008 (Closes: #991710)
+    If the IAX2 channel driver receives a packet that contains an unsupported
+    media format it can cause a crash to occur in Asterisk
+  * CVE-2021-32686 / AST-2021-009 (Closes: #991931)
+    pjproject/pjsip: crash when SSL socket destroyed during handshake
+
+ -- Bernhard Schmidt <berni at debian.org>  Fri, 06 Aug 2021 15:35:20 +0200
+
 asterisk (1:16.16.1~dfsg-1) unstable; urgency=medium
 
   * New minor upstream version 16.16.1~dfsg


=====================================
debian/patches/AST-2021-008-16.diff
=====================================
@@ -0,0 +1,126 @@
+From 2db19e3f2a26b5d0b6e7201349bb17cdfbc8c01b Mon Sep 17 00:00:00 2001
+From: Kevin Harwell <kharwell at sangoma.com>
+Date: Mon, 10 May 2021 17:59:00 -0500
+Subject: [PATCH] AST-2021-008 - chan_iax2: remote crash on unsupported media format
+
+If chan_iax2 received a packet with an unsupported media format, for
+example vp9, then it would set the frame's format to NULL. This could
+then result in a crash later when an attempt was made to access the
+format.
+
+This patch makes it so chan_iax2 now ignores/drops frames received
+with unsupported media format types.
+
+ASTERISK-29392 #close
+
+Change-Id: Ifa869a90dafe33eed8fd9463574fe6f1c0ad3eb1
+---
+
+diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
+index 3d8cd72..b43cf14 100644
+--- a/channels/chan_iax2.c
++++ b/channels/chan_iax2.c
+@@ -4132,6 +4132,7 @@
+ 	long ms;
+ 	long next;
+ 	struct timeval now = ast_tvnow();
++	struct ast_format *voicefmt;
+ 
+ 	/* Make sure we have a valid private structure before going on */
+ 	ast_mutex_lock(&iaxsl[callno]);
+@@ -4151,10 +4152,9 @@
+ 
+ 	ms = ast_tvdiff_ms(now, pvt->rxcore);
+ 
+-	if(ms >= (next = jb_next(pvt->jb))) {
+-		struct ast_format *voicefmt;
+-		voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
+-		ret = jb_get(pvt->jb, &frame, ms, voicefmt ? ast_format_get_default_ms(voicefmt) : 20);
++	voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
++	if (voicefmt && ms >= (next = jb_next(pvt->jb))) {
++		ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
+ 		switch(ret) {
+ 		case JB_OK:
+ 			fr = frame.data;
+@@ -4182,7 +4182,7 @@
+ 				pvt = iaxs[callno];
+ 			}
+ 		}
+-			break;
++		break;
+ 		case JB_DROP:
+ 			iax2_frame_free(frame.data);
+ 			break;
+@@ -6451,8 +6451,14 @@
+ 		f->frametype = fh->type;
+ 		if (f->frametype == AST_FRAME_VIDEO) {
+ 			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1));
++			if (!f->subclass.format) {
++				f->subclass.format = ast_format_none;
++			}
+ 		} else if (f->frametype == AST_FRAME_VOICE) {
+ 			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
++			if (!f->subclass.format) {
++				f->subclass.format = ast_format_none;
++			}
+ 		} else {
+ 			f->subclass.integer = uncompress_subclass(fh->csub);
+ 		}
+@@ -9929,8 +9935,8 @@
+ 		} else if (iaxs[fr->callno]->voiceformat == 0) {
+ 			ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
+ 			iax2_vnak(fr->callno);
+-		} else {
+-			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
++		} else if ((f.subclass.format = ast_format_compatibility_bitfield2format(
++						iaxs[fr->callno]->voiceformat))) {
+ 			f.datalen = len;
+ 			if (f.datalen >= 0) {
+ 				if (f.datalen)
+@@ -10173,11 +10179,17 @@
+ 		f.frametype = fh->type;
+ 		if (f.frametype == AST_FRAME_VIDEO) {
+ 			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40));
++			if (!f.subclass.format) {
++				return 1;
++			}
+ 			if ((fh->csub >> 6) & 0x1) {
+ 				f.subclass.frame_ending = 1;
+ 			}
+ 		} else if (f.frametype == AST_FRAME_VOICE) {
+ 			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
++			if (!f.subclass.format) {
++				return 1;
++			}
+ 		} else {
+ 			f.subclass.integer = uncompress_subclass(fh->csub);
+ 		}
+@@ -11795,6 +11807,11 @@
+ 				f.subclass.frame_ending = 1;
+ 			}
+ 			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->videoformat);
++			if (!f.subclass.format) {
++				ast_variables_destroy(ies.vars);
++				ast_mutex_unlock(&iaxsl[fr->callno]);
++				return 1;
++			}
+ 		} else {
+ 			ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
+ 			iax2_vnak(fr->callno);
+@@ -11816,9 +11833,14 @@
+ 	} else {
+ 		/* A mini frame */
+ 		f.frametype = AST_FRAME_VOICE;
+-		if (iaxs[fr->callno]->voiceformat > 0)
++		if (iaxs[fr->callno]->voiceformat > 0) {
+ 			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
+-		else {
++			if (!f.subclass.format) {
++				ast_variables_destroy(ies.vars);
++				ast_mutex_unlock(&iaxsl[fr->callno]);
++				return 1;
++			}
++		} else {
+ 			ast_debug(1, "Received mini frame before first full voice frame\n");
+ 			iax2_vnak(fr->callno);
+ 			ast_variables_destroy(ies.vars);


=====================================
debian/patches/AST-2021-009-16.diff
=====================================
@@ -0,0 +1,328 @@
+From 79b39abc0cbf0c50a30dd0935d299ae955486ca3 Mon Sep 17 00:00:00 2001
+From: Kevin Harwell <kharwell at sangoma.com>
+Date: Mon, 14 Jun 2021 13:28:25 -0500
+Subject: [PATCH] AST-2021-009 - pjproject-bundled: Avoid crash during handshake for TLS
+
+If an SSL socket parent/listener was destroyed during the handshake,
+depending on timing, it was possible for the handling callback to
+attempt access of it after the fact thus causing a crash.
+
+ASTERISK-29415 #close
+
+Change-Id: I105dacdcd130ea7fdd4cf2010ccf35b5eaf1432d
+---
+
+diff --git a/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch b/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch
+new file mode 100644
+index 0000000..81781f2
+--- /dev/null
++++ b/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch
+@@ -0,0 +1,166 @@
++From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001
++From: Nanang Izzuddin <nanang at 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(-)
++
++diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
++index bc468bcb3..abec31805 100644
++--- 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(pj_ssl_sock_t *ssock,
++ 
++     /* 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(pj_ssl_sock_t *ssock,
++ 		      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(pj_ssl_sock_t *ssock,
++ 
++ 	    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_complete (pj_activesock_t *asock,
++     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_complete (pj_activesock_t *asock,
++     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 */
++diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
++index 17b7ae3de..ce524d53f 100644
++--- 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_ssl_sock_t *ssock,
++     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_ssl_sock_t *ssock,
++     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_sock_t *ssock,
++ 			 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));
+diff --git a/third-party/pjproject/patches/0111-ssl-premature-destroy.patch b/third-party/pjproject/patches/0111-ssl-premature-destroy.patch
+new file mode 100644
+index 0000000..9de2915
+--- /dev/null
++++ b/third-party/pjproject/patches/0111-ssl-premature-destroy.patch
+@@ -0,0 +1,136 @@
++From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001
++From: Nanang Izzuddin <nanang at 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(-)
++
++diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
++index bc468bcb3..c2b8a846b 100644
++--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++++ b/pjlib/src/pj/ssl_sock_imp_common.c
++@@ -927,6 +927,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
++ 
++     /* 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;
++@@ -942,7 +943,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
++ 	    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);
++     }
++diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
++index a95b339a5..56841f80a 100644
++--- 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(char *action, pj_ssl_sock_t *ssock,
++ 	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(char *action, pj_ssl_sock_t *ssock,
++     /* 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 num, int rwflag, void *user_data)
++ }
++ 
++ 
++-/* 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, X509_STORE_CTX *x509_ctx)
++     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 *ssock)
++ 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


=====================================
debian/patches/series
=====================================
@@ -32,3 +32,6 @@ ffmpeg-includes.patch
 
 build-reproducibly
 autoreconf-pjproject
+
+AST-2021-008-16.diff
+AST-2021-009-16.diff



View it on GitLab: https://salsa.debian.org/pkg-voip-team/asterisk/-/compare/b85f524c1a1dd098d93b432e78353bdea6af17d3...c355df4f546aa2eeb29fafcae8a262e48622ca72

-- 
View it on GitLab: https://salsa.debian.org/pkg-voip-team/asterisk/-/compare/b85f524c1a1dd098d93b432e78353bdea6af17d3...c355df4f546aa2eeb29fafcae8a262e48622ca72
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-voip-maintainers/attachments/20211101/77654c3b/attachment-0001.htm>


More information about the Pkg-voip-maintainers mailing list