MT#57764 permissions: add func `allow_register_include_port()`

Introduce new function: `allow_register_include_port()`
to be able to check the whole Contact header including port.

Example, register.deny content is:
	ALL : "^sip:.*127.0.0.1:5062"

If the Contact is: "Contact: <sip:testuser1004@127.0.0.1:5062>"
then this will check the Contact hf including port of it.

Otherwise if usual `allow_register()` function is used,
then only the "testuser1004@127.0.0.1" will be taken into
account, which will lead the regex to be failing.

The func `allow_register_include_port()` works similarly
as `allow_register()` except it checks Contact's port.

Change-Id: I47820627e8ef91a09d7564d0848d5c356b3017d9
mr12.4
Donat Zenichev 1 year ago
parent a530d04507
commit dc673feada

@ -48,6 +48,7 @@ sipwise/presence_vqr.patch
sipwise/dialog-dlg_get_ttag.patch
sipwise/app_lua_sr-support-second-str-for-cfgutils-lock.patch
### active development
sipwise/permissions_add_register_allow_with_port_check.patch
#
### Don't just put stuff in any order
### use gbp pq import/export tooling to help maintain patches

@ -0,0 +1,131 @@
--- a/src/modules/permissions/permissions.c
+++ b/src/modules/permissions/permissions.c
@@ -123,6 +123,9 @@ static int allow_routing_2(
static int allow_register_1(struct sip_msg *msg, char *basename, char *s);
static int allow_register_2(
struct sip_msg *msg, char *allow_file, char *deny_file);
+static int allow_register_include_port_1(struct sip_msg *msg, char *basename, char *s);
+static int allow_register_include_port_2(
+ struct sip_msg *msg, char *allow_file, char *deny_file);
static int allow_uri(struct sip_msg *msg, char *basename, char *uri);
static int mod_init(void);
@@ -142,6 +145,10 @@ static cmd_export_t cmds[] = {
REQUEST_ROUTE | FAILURE_ROUTE},
{"allow_register", (cmd_function)allow_register_2, 2, load_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE},
+ {"allow_register_include_port", (cmd_function)allow_register_include_port_1, 1,
+ single_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE},
+ {"allow_register_include_port", (cmd_function)allow_register_include_port_2, 2,
+ load_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE},
{"allow_trusted", (cmd_function)allow_trusted_0, 0, 0, 0, ANY_ROUTE},
{"allow_trusted", (cmd_function)allow_trusted_2, 2, fixup_spve_spve,
fixup_free_spve_spve, ANY_ROUTE},
@@ -285,7 +292,7 @@ static int find_index(rule_file_t *array
* sip:username@domain, resulting buffer is statically allocated and
* zero terminated
*/
-static char *get_plain_uri(const str *uri)
+static char *get_plain_uri(const str *uri, int check_port)
{
static char buffer[EXPRESSION_LENGTH + 1];
struct sip_uri puri;
@@ -300,9 +307,14 @@ static char *get_plain_uri(const str *ur
}
if(puri.user.len) {
- len = puri.user.len + puri.host.len + 5;
+ len = puri.user.len + puri.host.len + 5; /* +5 is 'sip:' and '@' */
} else {
- len = puri.host.len + 4;
+ len = puri.host.len + 4; /* +4 is 'sip:' */
+ }
+
+ if(check_port && puri.port.len) {
+ LM_DBG("Port number will also be used to check the Contact value\n");
+ len += (puri.port.len + 1); /* +1 is ':' */
}
if(len > EXPRESSION_LENGTH) {
@@ -312,11 +324,19 @@ static char *get_plain_uri(const str *ur
strcpy(buffer, "sip:");
if(puri.user.len) {
- memcpy(buffer + 4, puri.user.s, puri.user.len);
+ memcpy(buffer + 4, puri.user.s, puri.user.len); /* +4 is 'sip:' */
buffer[puri.user.len + 4] = '@';
- memcpy(buffer + puri.user.len + 5, puri.host.s, puri.host.len);
+ memcpy(buffer + puri.user.len + 5, puri.host.s, puri.host.len); /* +5 is 'sip:' and '@' */
+ if (check_port && puri.port.len) {
+ buffer[puri.user.len + puri.host.len + 5] = ':';
+ memcpy(buffer + puri.user.len + puri.host.len + 6, puri.port.s, puri.port.len); /* +6 is 'sip:', '@' and ':' */
+ }
} else {
memcpy(buffer + 4, puri.host.s, puri.host.len);
+ if (check_port && puri.port.len) {
+ buffer[puri.host.len + 4] = ':';
+ memcpy(buffer + puri.host.len + 5, puri.port.s, puri.port.len); /* +5 is 'sip:' and ':' */
+ }
}
buffer[len] = '\0';
@@ -416,7 +436,7 @@ check_branches:
br_idx, &branch.len, &q, 0, 0, 0, 0, 0, 0, 0))
!= 0;
br_idx++) {
- uri_str = get_plain_uri(&branch);
+ uri_str = get_plain_uri(&branch, 0);
if(!uri_str) {
LM_ERR("failed to extract plain URI\n");
return -1;
@@ -755,9 +775,11 @@ int allow_routing_2(struct sip_msg *msg,
* against rules in allow and deny files passed as parameters. The function
* iterates over all Contacts and creates a pair with To for each contact
* found. That allows to restrict what IPs may be used in registrations, for
- * example
+ * example.
+ *
+ * If check_port is 0, then port isn't taken into account.
*/
-static int check_register(struct sip_msg *msg, int idx)
+static int check_register(struct sip_msg *msg, int idx, int check_port)
{
int len;
static char to_str[EXPRESSION_LENGTH + 1];
@@ -821,7 +843,8 @@ static int check_register(struct sip_msg
}
while(c) {
- contact_str = get_plain_uri(&c->uri);
+ /* if check_port = 1, then port is included into regex check */
+ contact_str = get_plain_uri(&c->uri, check_port);
if(!contact_str) {
LM_ERR("can't extract plain Contact URI\n");
return -1;
@@ -854,15 +877,23 @@ static int check_register(struct sip_msg
int allow_register_1(struct sip_msg *msg, char *basename, char *s)
{
- return check_register(msg, (int)(long)basename);
+ return check_register(msg, (int)(long)basename, 0);
}
-
int allow_register_2(struct sip_msg *msg, char *allow_file, char *deny_file)
{
- return check_register(msg, (int)(long)allow_file);
+ return check_register(msg, (int)(long)allow_file, 0);
}
+int allow_register_include_port_1(struct sip_msg *msg, char *basename, char *s)
+{
+ return check_register(msg, (int)(long)basename, 1);
+}
+
+int allow_register_include_port_2(struct sip_msg *msg, char *allow_file, char *deny_file)
+{
+ return check_register(msg, (int)(long)allow_file, 1);
+}
/*
* determines the permission to an uri
Loading…
Cancel
Save