CVE-2024-35190 (published 2024-05-17T17:15Z)

Asterisk is an open source private branch exchange and telephony toolkit. After upgrade to 18.23.0, ALL unauthorized SIP requests are identified as PJSIP Endpoint of local asterisk server. This vulnerability is fixed in 18.23.1, 20.8.1, and 21.3.1.\n


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/asterisk/asterisk
commit_details: repo_url: https://github.com/asterisk/asterisk
author: George Joseph
author_date: 2024-05-17 08:04:40-06:00
msg: Revert "res_pjsip_endpoint_identifier_ip: Add endpoint identifier transport address."

This reverts PR #602

Resolves: #GHSA-qqxj-v78h-hrf9
repository: repo_url: https://github.com/asterisk/asterisk
repo_name: asterisk/asterisk
description: The official Asterisk Project repository.
repo_language: C
owner: asterisk
file_changes: filename: pjsip.conf.sample
change_type: ModificationType.MODIFY
diff: @@ -197,47 +197,6 @@
 ;tcp_keepalive_interval_time=10  ; The time in seconds between individual keepalive probes
 ;tcp_keepalive_probe_count=5     ; The maximum number of keepalive probes TCP should send before dropping the connection
 
-;===============ENDPOINT IDENTIFIER TRANSPORT EXAMPLE==========================
-;
-; When Asterisk has multiple bound IP addresses, and endpoints don't use any
-; other means of identification (e.g.: username), the transports' bind addresses
-; can be used to identify them. Can be useful in case you're connecting to the
-; same ITSP multiple times on different IPs / NICs.
-;
-;[transport-eth0]
-;type=transport
-;protocol=tcp
-;bind=192.168.1.1:5060
-;
-;[transport-eth1]
-;type=transport
-;protocol=udp
-;bind=192.168.2.1:5060
-;
-;
-;[myprovider-a]
-;type=endpoint
-;transport=transport-eth0
-;identify_by=transport
-;
-;[myprovider-b]
-;type=endpoint
-;transport=transport-eth1
-;identify_by=transport
-;
-;
-;[identify-a]
-;type=identify
-;endpoint=myprovider-a
-;match=192.168.1.1:5060	; This is the bind address of [transport-eth0]
-;;transport=tcp		; Optionally, this is the transport protocol of [transport-eth0]
-;
-;[identify-b]
-;type=identify
-;endpoint=myprovider-b
-;match=192.168.2.1:5060	; This is the bind address of [transport-eth1]
-;;transport=udp		; Optionally, This is the transport protocol of [transport-eth1]
-
 ;===============OUTBOUND REGISTRATION WITH OUTBOUND AUTHENTICATION============
 ;
 ; This is a simple registration that works with some SIP trunking providers.
@@ -725,10 +684,9 @@
                         ; identified.
                         ; "username": Identify by the From or To username and domain
                         ; "auth_username": Identify by the Authorization username and realm
-                        ; "ip": Identify by the source (remote) IP address
+                        ; "ip": Identify by the source IP address
                         ; "header": Identify by a configured SIP header value.
                         ; "request_uri": Identify by the configured SIP request URI.
-                        ; "transport": Identify by the bound (local) IP address
                         ; In the username and auth_username cases, if an exact match
                         ; on both username and domain/realm fails, the match is
                         ; retried with just the username.
@@ -1313,10 +1271,9 @@
             ; (default: "no")
 ;endpoint_identifier_order=ip,username,anonymous
             ; The order by which endpoint identifiers are given priority.
-            ; Currently, "ip", "header", "request_uri", "transport", "username",
-            ; "auth_username" and "anonymous"  are valid identifiers as registered by
-            ; the res_pjsip_endpoint_identifier_* modules.
-            ; Some modules like res_pjsip_endpoint_identifier_user register
+            ; Currently, "ip", "header", "username", "auth_username" and "anonymous"
+            ; are valid identifiers as registered by the res_pjsip_endpoint_identifier_*
+            ; modules.  Some modules like res_pjsip_endpoint_identifier_user register
             ; more than one identifier.  Use the CLI command "pjsip show identifiers"
             ; to see the identifiers currently available.
             ; (default: ip,username,anonymous)
@@ -1504,8 +1461,6 @@
 ;match= ; Comma separated list of IP addresses, networks, or hostnames to match
         ; against (default: "")
 ;match_header= ; SIP header with specified value to match against (default: "")
-;match_request_uri= ; SIP request URI to match against (default: "")
-;transport= ; Match ageinst the transport protocol (tcp or udp) (default: "")
 ;type=  ; Must be of type identify (default: "")
 
 

programming_language: SQL
filename: bd9c5159c7ea_revert_d5122576cca8_add_transport_.py
change_type: ModificationType.ADD
diff: @@ -0,0 +1,22 @@
+"""Revert d5122576cca8 add transport attribute to identify
+
+Revision ID: bd9c5159c7ea
+Revises: 6c475a93f48a
+Create Date: 2024-05-17 08:30:58.299083
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'bd9c5159c7ea'
+down_revision = '6c475a93f48a'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.drop_column('ps_endpoint_id_ips', 'transport')
+
+
+def downgrade():
+    op.add_column('ps_endpoint_id_ips', sa.Column('transport', sa.String(128)))

programming_language: Python
filename: res_pjsip.h
change_type: ModificationType.MODIFY
diff: @@ -617,8 +617,6 @@ enum ast_sip_endpoint_identifier_type {
 	AST_SIP_ENDPOINT_IDENTIFY_BY_HEADER = (1 << 3),
 	/*! Identify based on request uri */
 	AST_SIP_ENDPOINT_IDENTIFY_BY_REQUEST_URI = (1 << 4),
-	/*! Identify based on bound (local) IP address */
-	AST_SIP_ENDPOINT_IDENTIFY_BY_TRANSPORT = (1 << 5),
 };
 AST_VECTOR(ast_sip_identify_by_vector, enum ast_sip_endpoint_identifier_type);
 

programming_language: C
filename: pjsip_config.xml
change_type: ModificationType.MODIFY
diff: @@ -565,14 +565,6 @@
 								but simply allowed by this configuration option.
 								</para>
 							</enum>
-							<enum name="transport">
-								<para>Matches the endpoint based on the destination IP
-								address.
-								</para>
-								<para>This method of identification is not configured here
-								but simply allowed by this configuration option.
-								</para>
-							</enum>
 						</enumlist>
 					</description>
 				</configOption>

programming_language: HTML
filename: pjsip_configuration.c
change_type: ModificationType.MODIFY
diff: @@ -426,9 +426,6 @@ static const char *sip_endpoint_identifier_type2str(enum ast_sip_endpoint_identi
 	case AST_SIP_ENDPOINT_IDENTIFY_BY_REQUEST_URI:
 		str = "request_uri";
 		break;
-	case AST_SIP_ENDPOINT_IDENTIFY_BY_TRANSPORT:
-		str = "transport";
-		break;
 	}
 	return str;
 }
@@ -456,8 +453,6 @@ static int sip_endpoint_identifier_str2type(const char *str)
 		method = AST_SIP_ENDPOINT_IDENTIFY_BY_HEADER;
 	} else if (!strcasecmp(str, "request_uri")) {
 		method = AST_SIP_ENDPOINT_IDENTIFY_BY_REQUEST_URI;
-	} else if (!strcasecmp(str, "transport")) {
-		method = AST_SIP_ENDPOINT_IDENTIFY_BY_TRANSPORT;
 	} else {
 		method = -1;
 	}

programming_language: C
filename: res_pjsip_endpoint_identifier_ip.c
change_type: ModificationType.MODIFY
diff: @@ -124,16 +124,6 @@
 						</para></note>
 					</description>
 				</configOption>
-				<configOption name="transport">
-					<synopsis>Match against a transport type.</synopsis>
-					<description>
-						<para>When using the ip or transport identifier, this option
-						can be used to match the transport type <literal>(udp or tcp)
-						</literal> as well.</para>
-						<para>When omitted, or left empty, which is the default, it
-						won't match against the transport type.</para>
-					</description>
-				</configOption>
 				<configOption name="type">
 					<synopsis>Must be of type 'identify'.</synopsis>
 				</configOption>
@@ -161,8 +151,6 @@ struct ip_identify_match {
 		AST_STRING_FIELD(match_header_name);
 		/*! SIP header value of the match_header string */
 		AST_STRING_FIELD(match_header_value);
-		/*! The name of the transport type */
-		AST_STRING_FIELD(transport);
 	);
 	/*! Compiled match_header regular expression when is_header_regex is non-zero */
 	regex_t regex_header_buf;
@@ -180,12 +168,6 @@ struct ip_identify_match {
 	unsigned int is_request_uri_regex:1;
 };
 
-/*! \brief Structure for a socket address with transport */
-struct ast_sockaddr_with_tp {
-	struct ast_sockaddr addr;
-	char tp[128];
-};
-
 /*! \brief Destructor function for a matching object */
 static void ip_identify_destroy(void *obj)
 {
@@ -321,29 +303,18 @@ static int request_identify_match_check(void *obj, void *arg, int flags)
 static int ip_identify_match_check(void *obj, void *arg, int flags)
 {
 	struct ip_identify_match *identify = obj;
-	struct ast_sockaddr_with_tp *addr_with_tp = arg;
-	struct ast_sockaddr address = addr_with_tp->addr;
+	struct ast_sockaddr *addr = arg;
 	int sense;
 
-	sense = ast_apply_ha(identify->matches, &address);
+	sense = ast_apply_ha(identify->matches, addr);
 	if (sense != AST_SENSE_ALLOW) {
-		ast_debug(3, "Address %s matches identify '%s'\n",
-				ast_sockaddr_stringify(&address),
-				ast_sorcery_object_get_id(identify));
-		if (ast_strlen_zero(identify->transport) || !strcasecmp(identify->transport, addr_with_tp->tp)) {
-			ast_debug(3, "Transport %s matches identify '%s'\n",
-				addr_with_tp->tp,
-				ast_sorcery_object_get_id(identify));
-			return CMP_MATCH;
-		} else {
-			ast_debug(3, "Transport %s match not matched identify '%s'\n",
-				addr_with_tp->tp,
+		ast_debug(3, "Source address %s matches identify '%s'\n",
+				ast_sockaddr_stringify(addr),
 				ast_sorcery_object_get_id(identify));
-			return 0;
-		}
+		return CMP_MATCH;
 	} else {
-		ast_debug(3, "Address %s does not match identify '%s'\n",
-				ast_sockaddr_stringify(&address),
+		ast_debug(3, "Source address %s does not match identify '%s'\n",
+				ast_sockaddr_stringify(addr),
 				ast_sorcery_object_get_id(identify));
 		return 0;
 	}
@@ -384,54 +355,18 @@ static struct ast_sip_endpoint *common_identify(ao2_callback_fn *identify_match_
 
 static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
 {
-	struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
-	pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
-
-	ast_sockaddr_parse(&addr_with_tp.addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
-	ast_sockaddr_set_port(&addr_with_tp.addr, rdata->pkt_info.src_port);
-
-	return common_identify(ip_identify_match_check, &addr_with_tp);
-}
-
-static struct ast_sip_endpoint *transport_identify(pjsip_rx_data *rdata)
-{
-	char buffer[PJ_INET6_ADDRSTRLEN];
-	pj_status_t status;
-	struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
-	union pj_sockaddr sock = rdata->tp_info.transport->local_addr;
-
-	pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
-
-	if (sock.addr.sa_family == PJ_AF_INET6) {
-		status = pj_inet_ntop(PJ_AF_INET6, &(sock.ipv6.sin6_addr), buffer, PJ_INET6_ADDRSTRLEN);
-		if (status == PJ_SUCCESS && !strcmp(buffer, "::")) {
-			ast_log(LOG_WARNING, "Matching against '::' may be unpredictable.\n");
-		}
-	} else {
-		status = pj_inet_ntop(PJ_AF_INET, &(sock.ipv4.sin_addr), buffer, PJ_INET_ADDRSTRLEN);
-		if (status == PJ_SUCCESS && !strcmp(buffer, "0.0.0.0")) {
-			ast_log(LOG_WARNING, "Matching against '0.0.0.0' may be unpredictable.\n");
-		}
-	}
+	struct ast_sockaddr addr = { { 0, } };
 
-	if (status == PJ_SUCCESS) {
-		ast_sockaddr_parse(&addr_with_tp.addr, buffer, PARSE_PORT_FORBID);
-		ast_sockaddr_set_port(&addr_with_tp.addr, rdata->tp_info.transport->local_name.port);
+	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
 
-		return common_identify(ip_identify_match_check, &addr_with_tp);
-	} else {
-		return NULL;
-	}
+	return common_identify(ip_identify_match_check, &addr);
 }
 
 static struct ast_sip_endpoint_identifier ip_identifier = {
 	.identify_endpoint = ip_identify,
 };
 
-static struct ast_sip_endpoint_identifier transport_identifier = {
-	.identify_endpoint = transport_identify,
-};
-
 static struct ast_sip_endpoint *header_identify(pjsip_rx_data *rdata)
 {
 	return common_identify(header_identify_match_check, rdata);
@@ -595,12 +530,6 @@ static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
 		return -1;
 	}
 
-	if (!ast_strlen_zero(identify->transport)) {
-		if (ast_string_field_set(identify, transport, identify->transport)) {
-			return -1;
-		}
-	}
-
 	if (!ast_strlen_zero(identify->match_header)) {
 		char *c_header;
 		char *c_value;
@@ -950,13 +879,6 @@ static int cli_print_body(void *obj, void *arg, int flags)
 				addr, ast_sockaddr_cidr_bits(&match->netmask));
 		}
 
-		if (!ast_strlen_zero(ident->transport)) {
-			ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
-				indent,
-				"Transport",
-				ident->transport);
-		}
-
 		if (!ast_strlen_zero(ident->match_header)) {
 			ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
 				indent,
@@ -1032,13 +954,11 @@ static int load_module(void)
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_request_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_request_uri));
 	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
-	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, transport));
 	ast_sorcery_load_object(ast_sip_get_sorcery(), "identify");
 
 	ast_sip_register_endpoint_identifier_with_name(&ip_identifier, "ip");
 	ast_sip_register_endpoint_identifier_with_name(&header_identifier, "header");
 	ast_sip_register_endpoint_identifier_with_name(&request_identifier, "request_uri");
-	ast_sip_register_endpoint_identifier_with_name(&transport_identifier, "transport");
 	ast_sip_register_endpoint_formatter(&endpoint_identify_formatter);
 
 	cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
@@ -1075,7 +995,6 @@ static int unload_module(void)
 	ast_sip_unregister_endpoint_identifier(&header_identifier);
 	ast_sip_unregister_endpoint_identifier(&request_identifier);
 	ast_sip_unregister_endpoint_identifier(&ip_identifier);
-	ast_sip_unregister_endpoint_identifier(&transport_identifier);
 
 	return 0;
 }

programming_language: C