asterisk-15.x: patch AST-2018-007 and 008 344/head
authorSebastian Kemper <sebastian_ml@gmx.net>
Tue, 26 Jun 2018 17:39:59 +0000 (19:39 +0200)
committerSebastian Kemper <sebastian_ml@gmx.net>
Tue, 26 Jun 2018 17:40:01 +0000 (19:40 +0200)
Patches from upstream for:

AST-2018-007
AST-2018-008

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
net/asterisk-15.x/Makefile
net/asterisk-15.x/patches/110-AST-2018-007-15.diff [new file with mode: 0644]
net/asterisk-15.x/patches/120-AST-2018-008-15.diff [new file with mode: 0644]

index 9825de2c02bd5c9076856c0fef97881e28887511..b17d89f85b62b9d9f373e977f138ef190d1e07a1 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=asterisk15
 PKG_VERSION:=15.3.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases
diff --git a/net/asterisk-15.x/patches/110-AST-2018-007-15.diff b/net/asterisk-15.x/patches/110-AST-2018-007-15.diff
new file mode 100644 (file)
index 0000000..8f12808
--- /dev/null
@@ -0,0 +1,49 @@
+From 380b5ae0a1e4a68bfb098319a7ab86d3d34c2fcb Mon Sep 17 00:00:00 2001
+From: Sean Bright <sean.bright@gmail.com>
+Date: Mon, 16 Apr 2018 15:13:58 -0400
+Subject: [PATCH] AST-2018-007: iostreams potential DoS when client connection closed prematurely
+
+Before Asterisk sends an HTTP response (at least in the case of errors),
+it attempts to read & discard the content of the request. If the client
+lies about the Content-Length, or the connection is closed from the
+client side before "Content-Length" bytes are sent, the request handling
+thread will busy loop.
+
+ASTERISK-27807
+
+Change-Id: I945c5fc888ed92be625b8c35039fc6d2aa89c762
+---
+
+diff --git a/main/iostream.c b/main/iostream.c
+index 4cddd43..20188cb 100644
+--- a/main/iostream.c
++++ b/main/iostream.c
+@@ -197,11 +197,18 @@
+                                       }
+                               }
+                               break;
++                      case SSL_ERROR_SYSCALL:
++                              /* Some non-recoverable I/O error occurred. The OpenSSL error queue may
++                               * contain more information on the error. For socket I/O on Unix systems,
++                               * consult errno for details. */
++                              ast_debug(1, "TLS non-recoverable I/O error occurred: %s, %s\n", ERR_error_string(sslerr, err),
++                                      ssl_error_to_string(sslerr, res));
++                              return -1;
+                       default:
+                               /* Report EOF for an undecoded SSL or transport error. */
+                               ast_debug(1, "TLS transport or SSL error reading data:  %s, %s\n", ERR_error_string(sslerr, err),
+                                       ssl_error_to_string(sslerr, res));
+-                              return 0;
++                              return -1;
+                       }
+                       if (!ms) {
+                               /* Report EOF for a timeout */
+@@ -317,7 +324,7 @@
+       while (remaining) {
+               ret = ast_iostream_read(stream, buf, remaining > sizeof(buf) ? sizeof(buf) : remaining);
+-              if (ret < 0) {
++              if (ret <= 0) {
+                       return ret;
+               }
+               remaining -= ret;
diff --git a/net/asterisk-15.x/patches/120-AST-2018-008-15.diff b/net/asterisk-15.x/patches/120-AST-2018-008-15.diff
new file mode 100644 (file)
index 0000000..2130c7d
--- /dev/null
@@ -0,0 +1,101 @@
+From f597032e833a4d3e8e710e5b1416ba780f002b8b Mon Sep 17 00:00:00 2001
+From: Richard Mudgett <rmudgett@digium.com>
+Date: Mon, 30 Apr 2018 17:38:58 -0500
+Subject: [PATCH] AST-2018-008: Fix enumeration of endpoints from ACL rejected addresses.
+
+When endpoint specific ACL rules block a SIP request they respond with a
+403 forbidden.  However, if an endpoint is not identified then a 401
+unauthorized response is sent.  This vulnerability just discloses which
+requests hit a defined endpoint.  The ACL rules cannot be bypassed to gain
+access to the disclosed endpoints.
+
+* Made endpoint specific ACL rules now respond with a 401 unauthorized
+which is the same as if an endpoint were not identified.  The fix is
+accomplished by replacing the found endpoint with the artificial endpoint
+which always fails authentication.
+
+ASTERISK-27818
+
+Change-Id: Icb275a54ff8e2df6c671a6d9bda37b5d732b3b32
+---
+
+diff --git a/res/res_pjsip/pjsip_distributor.c b/res/res_pjsip/pjsip_distributor.c
+index 51b95a2..0af447d 100644
+--- a/res/res_pjsip/pjsip_distributor.c
++++ b/res/res_pjsip/pjsip_distributor.c
+@@ -676,6 +676,26 @@
+       ao2_unlock(unid);
+ }
++static int apply_endpoint_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint);
++static int apply_endpoint_contact_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint);
++
++static void apply_acls(pjsip_rx_data *rdata)
++{
++      struct ast_sip_endpoint *endpoint;
++
++      /* Is the endpoint allowed with the source or contact address? */
++      endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
++      if (endpoint != artificial_endpoint
++              && (apply_endpoint_acl(rdata, endpoint)
++                      || apply_endpoint_contact_acl(rdata, endpoint))) {
++              ast_debug(1, "Endpoint '%s' not allowed by ACL\n",
++                      ast_sorcery_object_get_id(endpoint));
++
++              /* Replace the rdata endpoint with the artificial endpoint. */
++              ao2_replace(rdata->endpt_info.mod_data[endpoint_mod.id], artificial_endpoint);
++      }
++}
++
+ static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata)
+ {
+       struct ast_sip_endpoint *endpoint;
+@@ -695,6 +715,7 @@
+                       ao2_unlink(unidentified_requests, unid);
+                       ao2_ref(unid, -1);
+               }
++              apply_acls(rdata);
+               return PJ_FALSE;
+       }
+@@ -759,6 +780,8 @@
+                       ast_sip_report_invalid_endpoint(name, rdata);
+               }
+       }
++
++      apply_acls(rdata);
+       return PJ_FALSE;
+ }
+@@ -842,16 +865,11 @@
+       ast_assert(endpoint != NULL);
+-      if (endpoint!=artificial_endpoint) {
+-              if (apply_endpoint_acl(rdata, endpoint) || apply_endpoint_contact_acl(rdata, endpoint)) {
+-                      if (!is_ack) {
+-                              pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+-                      }
+-                      return PJ_TRUE;
+-              }
++      if (is_ack) {
++              return PJ_FALSE;
+       }
+-      if (!is_ack && ast_sip_requires_authentication(endpoint, rdata)) {
++      if (ast_sip_requires_authentication(endpoint, rdata)) {
+               pjsip_tx_data *tdata;
+               struct unidentified_request *unid;
+@@ -888,6 +906,10 @@
+                       return PJ_TRUE;
+               }
+               pjsip_tx_data_dec_ref(tdata);
++      } else if (endpoint == artificial_endpoint) {
++              /* Uh. Oh.  The artificial endpoint couldn't challenge so block the request. */
++              pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
++              return PJ_TRUE;
+       }
+       return PJ_FALSE;
+