diff --git a/debian/patches/series b/debian/patches/series index e3cb5c0c3..9efd85c17 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -38,6 +38,8 @@ sipwise/Revert-pua_dialoginfo-disable-publish-notifications-.patch ## upstream master upstream/pv_headers-fix-removal-of-all-values-on-when-using-P.patch upstream/pv_headers-pvh_set_header-remove-values-to-set-null-.patch +upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch +upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch ### relevant for upstream sipwise/pua_dialoginfo-refresh_pubruri_avps_flag.patch sipwise/pua_dialoginfo-local_identity_dlg_var.patch diff --git a/debian/patches/upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch b/debian/patches/upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch new file mode 100644 index 000000000..162cbc46c --- /dev/null +++ b/debian/patches/upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch @@ -0,0 +1,48 @@ +From 536736f2529f7554929f3aa6b74ac616c382bc6e Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Tue, 24 Aug 2021 18:50:16 +0300 +Subject: [PATCH 1/2] lcr: remove excessive checks for the 'src_port' accuracy + +Remove unneeded check for 'src_port' in: +- ki_from_any_gw_addr() +- ki_from_gw_addr() + +Which makes no sense because 'src_port' is of type 'unsigned int', +and the check concerns whether it's less than 0 or not. +--- + src/modules/lcr/lcr_mod.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c +index 858352f2c7..57b4021ac9 100644 +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -3093,9 +3093,9 @@ static int ki_from_gw_addr( + return -1; + } + +- /* src_port set to 0 means we don't want to check it */ +- if((src_port < 0) || (src_port > 65535)) { +- LM_ERR("invalid port parameter value %d\n", transport); ++ /* src_port set to 0 is allowed and means we don't want to check it */ ++ if(src_port > 65535) { ++ LM_ERR("invalid port parameter value %d\n", src_port); + return -1; + } + +@@ -3215,9 +3215,9 @@ static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport, unsi + return -1; + } + +- /* src_port set to 0 means we don't want to check it */ +- if((src_port < 0) || (src_port > 65535)) { +- LM_ERR("invalid port parameter value %d\n", transport); ++ /* src_port set to 0 is allowed and means we don't want to check it */ ++ if(src_port > 65535) { ++ LM_ERR("invalid port parameter value %d\n", src_port); + return -1; + } + +-- +2.25.1 + diff --git a/debian/patches/upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch b/debian/patches/upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch new file mode 100644 index 000000000..14430c541 --- /dev/null +++ b/debian/patches/upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch @@ -0,0 +1,338 @@ +From 9115d74b33aefb0febad7c7fffe7d184e4066b77 Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +Date: Mon, 23 Aug 2021 21:50:50 +0300 +Subject: [PATCH 2/2] lcr: source port check for from_any_gw() and from_gw(). + +A simple change, which allows to check, if a coming request matches +not only by an IP address and a transport protocol, +but also using the source port of a request. + +Improvements are done for the following functions of the lcr module: +- from_any_gw() +- from_gw() + +Back compatibility provided, hence it does not affect already existing behavior. +--- + src/modules/lcr/doc/lcr_admin.xml | 31 ++++---- + src/modules/lcr/lcr_mod.c | 116 +++++++++++++++++++++++++----- + 2 files changed, 116 insertions(+), 31 deletions(-) + +diff --git a/src/modules/lcr/doc/lcr_admin.xml b/src/modules/lcr/doc/lcr_admin.xml +index 2c5bfb0d85..f6461e1a24 100644 +--- a/src/modules/lcr/doc/lcr_admin.xml ++++ b/src/modules/lcr/doc/lcr_admin.xml +@@ -1425,16 +1425,16 @@ defunct_gw(60); + +
+ +- <function moreinfo="none">from_gw(lcr_id[, ip_addr, proto])</function> ++ <function moreinfo="none">from_gw(lcr_id[, ip_addr, proto[, src_port]])</function> + + +- Checks if request comes from IP address and transport protocol ++ Checks if request comes from IP address, transport protocol and source port + specified for a gateway in LCR instance lcr_id. + Fails if the LCR instance includes + one or more gateways without IP address. +- IP address and transport protocol to be checked are either +- taken from source IP address of the request or +- (if present) from ip_addr and proto arguments. ++ IP address, transport protocol and source port to be checked are either ++ taken from source IP address and port of the request or ++ (if present) from ip_addr, proto and src_port arguments. + + + lcr_id can be an integer constant or a pseudo variable +@@ -1442,7 +1442,8 @@ defunct_gw(60); + variable holding a string value. proto can be an integer + constant (0 = ANY, 1 = UDP, 2 = TCP, + 3 = TLS, 4 = SCTP) or a pseudo variable holding such an +- integer value. ++ integer value. src_port can be an integer or a pseudo variable ++ holding such an integer value. + + + If request comes from a gateway, gateway's tag and flags are +@@ -1466,7 +1467,7 @@ defunct_gw(60); + <function>from_gw</function> usage + + ... +-if (from_gw(1, $avp(real_source_addr), 2) { ++if (from_gw(1, $avp(real_source_addr), 2, 5060) { + ... + }; + ... +@@ -1476,21 +1477,21 @@ if (from_gw(1, $avp(real_source_addr), 2) { + +
+ +- <function moreinfo="none">from_any_gw([ip_addr, proto])</function> ++ <function moreinfo="none">from_any_gw([ip_addr, proto[, src_port]])</function> + + +- Checks if request comes from IP address and transport +- protocol specified for any gateway. Only LCR instances, ++ Checks if request comes from IP address, transport protocol and source port ++ specified for any gateway. Only LCR instances, + where all gateways + have IP address, are included in the test. +- IP address and transport protocol to be checked are either +- taken from source IP address and transport protocol ++ IP address, transport protocol and source port to be checked are either ++ taken from source IP address, transport protocol and source port + of the request or +- (if present) from ip_addr and proto arguments. See from_gw() ++ (if present) from ip_addr, proto and src_port arguments. See from_gw() + function for more info about the arguments. + + +- If any gateway has the IP address and transport protocol, ++ If any gateway has the IP address, transport protocol and source port, + function returns LCR + identifier of the gateway. Returns -1 on error or if + the request does not come from a gateway. +@@ -1515,7 +1516,7 @@ if (from_gw(1, $avp(real_source_addr), 2) { + <function>from_gw</function> usage + + ... +-$var(lcr_id) = from_any_gw("192.168.1.1", 3); ++$var(lcr_id) = from_any_gw("192.168.1.1", 3, 5061); + ... + + +diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c +index 579ec06d4d..858352f2c7 100644 +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -260,8 +260,10 @@ static int inactivate_gw(struct sip_msg *_m, char *_s1, char *_s2); + static int defunct_gw(struct sip_msg *_m, char *_s1, char *_s2); + static int from_gw_1(struct sip_msg *_m, char *_s1, char *_s2); + static int from_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3); ++static int from_gw_4(struct sip_msg *_m, char *_s1, char *_s2, char *_s3, char *_s4); + static int from_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2); + static int from_any_gw_2(struct sip_msg *_m, char *_s1, char *_s2); ++static int from_any_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3); + static int to_gw_1(struct sip_msg *_m, char *_s1, char *_s2); + static int to_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3); + static int to_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2); +@@ -283,10 +285,14 @@ static cmd_export_t cmds[] = { + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"from_gw", (cmd_function)from_gw_3, 3, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, ++ {"from_gw", (cmd_function)from_gw_4, 4, 0, 0, ++ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"from_any_gw", (cmd_function)from_any_gw_0, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"from_any_gw", (cmd_function)from_any_gw_2, 2, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, ++ {"from_any_gw", (cmd_function)from_any_gw_3, 3, 0, 0, ++ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"to_gw", (cmd_function)to_gw_1, 1, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"to_gw", (cmd_function)to_gw_3, 3, 0, 0, +@@ -2978,7 +2984,7 @@ static int next_gw(struct sip_msg *_m, char *_s1, char *_s2) + * Checks if request comes from ip address of a gateway + */ + static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id, +- struct ip_addr *src_addr, uri_transport transport) ++ struct ip_addr *src_addr, uri_transport transport, unsigned int src_port) + { + struct gw_info *res, gw, *gws; + int_str val; +@@ -2997,9 +3003,10 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id, + sizeof(struct gw_info), comp_gws); + + /* Store tag and flags and return result */ +- if((res != NULL) && ((transport == PROTO_NONE) +- || (res->transport_code == transport))) { +- LM_DBG("request game from gw\n"); ++ if((res != NULL) ++ && ((transport == PROTO_NONE) || (res->transport_code == transport)) ++ && ((src_port == 0) || (res->port == src_port))) { ++ LM_DBG("request came from gw\n"); + if(tag_avp_param) { + val.s.s = res->tag; + val.s.len = res->tag_len; +@@ -3021,22 +3028,24 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id, + + /* + * Checks if request comes from ip address of a gateway taking source +- * address and transport protocol from request. ++ * address, transport protocol and source port from request. + */ + static int ki_from_gw(sip_msg_t *_m, int lcr_id) + { + uri_transport transport; ++ unsigned int src_port; + + if((lcr_id < 1) || (lcr_id > lcr_count_param)) { + LM_ERR("invalid lcr_id parameter value %d\n", lcr_id); + return -1; + } + +- /* Get transport protocol */ ++ /* Get transport protocol and port */ + transport = _m->rcv.proto; ++ src_port = _m->rcv.src_port; + + /* Do test */ +- return do_from_gw(_m, lcr_id, &_m->rcv.src_ip, transport); ++ return do_from_gw(_m, lcr_id, &_m->rcv.src_ip, transport, src_port); + } + + static int from_gw_1(struct sip_msg *_m, char *_lcr_id, char *_s2) +@@ -3056,10 +3065,10 @@ static int from_gw_1(struct sip_msg *_m, char *_lcr_id, char *_s2) + + /* + * Checks if request comes from ip address of a gateway taking source +- * address and transport protocol from parameters ++ * address, transport protocol and source port from parameters. + */ + static int ki_from_gw_addr( +- sip_msg_t *_m, int lcr_id, str *addr_str, int transport) ++ sip_msg_t *_m, int lcr_id, str *addr_str, int transport, unsigned int src_port) + { + struct ip_addr src_addr; + struct ip_addr *ip; +@@ -3084,8 +3093,14 @@ static int ki_from_gw_addr( + return -1; + } + ++ /* src_port set to 0 means we don't want to check it */ ++ if((src_port < 0) || (src_port > 65535)) { ++ LM_ERR("invalid port parameter value %d\n", transport); ++ return -1; ++ } ++ + /* Do test */ +- return do_from_gw(_m, lcr_id, &src_addr, transport); ++ return do_from_gw(_m, lcr_id, &src_addr, transport, src_port); + } + + static int from_gw_3( +@@ -3112,7 +3127,41 @@ static int from_gw_3( + return -1; + } + +- return ki_from_gw_addr(_m, lcr_id, &addr_str, transport); ++ return ki_from_gw_addr(_m, lcr_id, &addr_str, transport, 0); ++} ++ ++static int from_gw_4( ++ struct sip_msg *_m, char *_lcr_id, char *_addr, char *_transport, char *_src_port) ++{ ++ int lcr_id; ++ str addr_str; ++ char *tmp; ++ uri_transport transport; ++ unsigned int src_port; ++ ++ /* Get and check parameter values */ ++ lcr_id = strtol(_lcr_id, &tmp, 10); ++ if((tmp == 0) || (*tmp) || (tmp == _lcr_id)) { ++ LM_ERR("invalid lcr_id parameter %s\n", _lcr_id); ++ return -1; ++ } ++ ++ addr_str.s = _addr; ++ addr_str.len = strlen(_addr); ++ ++ transport = strtol(_transport, &tmp, 10); ++ if((tmp == 0) || (*tmp) || (tmp == _transport)) { ++ LM_ERR("invalid transport parameter %s\n", _lcr_id); ++ return -1; ++ } ++ tmp=0; ++ src_port = strtol(_src_port, &tmp, 10); ++ if((tmp == 0) || (*tmp) || (tmp == _src_port)) { ++ LM_ERR("invalid port parameter %s\n", _src_port); ++ return -1; ++ } ++ ++ return ki_from_gw_addr(_m, lcr_id, &addr_str, transport, src_port); + } + + /* +@@ -3123,11 +3172,14 @@ static int ki_from_any_gw(sip_msg_t *_m) + { + unsigned int i; + uri_transport transport; ++ unsigned int src_port; + ++ /* Get transport protocol and port */ + transport = _m->rcv.proto; ++ src_port = _m->rcv.src_port; + + for(i = 1; i <= lcr_count_param; i++) { +- if(do_from_gw(_m, i, &_m->rcv.src_ip, transport) == 1) { ++ if(do_from_gw(_m, i, &_m->rcv.src_ip, transport, src_port) == 1) { + return i; + } + } +@@ -3141,9 +3193,9 @@ static int from_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2) + + /* + * Checks if request comes from ip address of a a gateway taking source +- * IP address and transport protocol from parameters. ++ * IP address, transport protocol and source port from parameters. + */ +-static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport) ++static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport, unsigned int src_port) + { + unsigned int i; + struct ip_addr *ip, src_addr; +@@ -3163,9 +3215,15 @@ static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport) + return -1; + } + ++ /* src_port set to 0 means we don't want to check it */ ++ if((src_port < 0) || (src_port > 65535)) { ++ LM_ERR("invalid port parameter value %d\n", transport); ++ return -1; ++ } ++ + /* Do test */ + for(i = 1; i <= lcr_count_param; i++) { +- if(do_from_gw(_m, i, &src_addr, transport) == 1) { ++ if(do_from_gw(_m, i, &src_addr, transport, src_port) == 1) { + return i; + } + } +@@ -3188,7 +3246,33 @@ static int from_any_gw_2(struct sip_msg *_m, char *_addr, char *_transport) + return -1; + } + +- return ki_from_any_gw_addr(_m, &addr_str, transport); ++ return ki_from_any_gw_addr(_m, &addr_str, transport, 0); ++} ++ ++static int from_any_gw_3(struct sip_msg *_m, char *_addr, char *_transport, char *_src_port) ++{ ++ str addr_str; ++ uri_transport transport; ++ unsigned int src_port; ++ char *tmp; ++ ++ /* Get and check parameter values */ ++ addr_str.s = _addr; ++ addr_str.len = strlen(_addr); ++ ++ transport = strtol(_transport, &tmp, 10); ++ if((tmp == 0) || (*tmp) || (tmp == _transport)) { ++ LM_ERR("invalid transport parameter %s\n", _transport); ++ return -1; ++ } ++ tmp=0; ++ src_port = strtol(_src_port, &tmp, 10); ++ if((tmp == 0) || (*tmp) || (tmp == _src_port)) { ++ LM_ERR("invalid port parameter %s\n", _src_port); ++ return -1; ++ } ++ ++ return ki_from_any_gw_addr(_m, &addr_str, transport, src_port); + } + + /* +-- +2.25.1 +