- allow_trusted() now can take optional parameter of value to match.
- provided parameter will be used instead of From header in match_res() and match_hash_table()
- documentation extended with 3-arguments allow_trusted() function description
... | ... |
@@ -254,7 +254,7 @@ |
254 | 254 |
<listitem> |
255 | 255 |
<para> |
256 | 256 |
regular expression is either empty (NULL in |
257 |
- database) or matches the From URI of request. |
|
257 |
+ database) or matches the request's From (or optionally provided) URI. |
|
258 | 258 |
</para> |
259 | 259 |
</listitem> |
260 | 260 |
</itemizedlist> |
... | ... |
@@ -1185,12 +1185,12 @@ if ($var(group) != -1) { |
1185 | 1185 |
</section> |
1186 | 1186 |
<section id ="permissions.f.allow_trusted"> |
1187 | 1187 |
<title> |
1188 |
- <function moreinfo="none">allow_trusted([src_ip_pvar, proto_pvar])</function> |
|
1188 |
+ <function moreinfo="none">allow_trusted([src_ip_pvar, proto_pvar, uri_pvar])</function> |
|
1189 | 1189 |
</title> |
1190 | 1190 |
<para> |
1191 | 1191 |
Checks based either on request's source address and transport |
1192 | 1192 |
protocol or source address and transport protocol given |
1193 |
- in pvar arguments, and From URI of request |
|
1193 |
+ in pvar arguments, and From URI of request (or uri_pvar if provided) |
|
1194 | 1194 |
if request can be trusted without |
1195 | 1195 |
authentication. Returns <quote>1</quote> if a match is found |
1196 | 1196 |
as described in <xref linkend="sec-trusted-requests"/> |
... | ... |
@@ -1200,7 +1200,7 @@ if ($var(group) != -1) { |
1200 | 1200 |
matching peer to AVP peer_tag_avp. |
1201 | 1201 |
</para> |
1202 | 1202 |
<para> |
1203 |
- Source address and transport protocol given in pvar |
|
1203 |
+ Source address, transport protocol and uri given in pvar |
|
1204 | 1204 |
arguments must be in string format. Valid transport |
1205 | 1205 |
protocol values are (ignoring case) "any", "udp, "tcp", "tls", |
1206 | 1206 |
"ws", "wss" and "sctp". |
... | ... |
@@ -250,10 +250,10 @@ int hash_table_insert(struct trusted_list** table, char* src_ip, |
250 | 250 |
* Returns number of matches or -1 if none matched. |
251 | 251 |
*/ |
252 | 252 |
int match_hash_table(struct trusted_list** table, struct sip_msg* msg, |
253 |
- char *src_ip_c_str, int proto) |
|
253 |
+ char *src_ip_c_str, int proto, char *uri) |
|
254 | 254 |
{ |
255 |
- str uri, ruri; |
|
256 |
- char uri_string[MAX_URI_SIZE + 1]; |
|
255 |
+ LM_DBG("match_hash_table src_ip: %s, proto: %d, uri: %s\n", src_ip_c_str, proto, uri); |
|
256 |
+ str ruri; |
|
257 | 257 |
char ruri_string[MAX_URI_SIZE + 1]; |
258 | 258 |
regex_t preg; |
259 | 259 |
struct trusted_list *np; |
... | ... |
@@ -266,14 +266,6 @@ int match_hash_table(struct trusted_list** table, struct sip_msg* msg, |
266 | 266 |
|
267 | 267 |
if (IS_SIP(msg)) |
268 | 268 |
{ |
269 |
- if (parse_from_header(msg) < 0) return -1; |
|
270 |
- uri = get_from(msg)->uri; |
|
271 |
- if (uri.len > MAX_URI_SIZE) { |
|
272 |
- LM_ERR("from URI too large\n"); |
|
273 |
- return -1; |
|
274 |
- } |
|
275 |
- memcpy(uri_string, uri.s, uri.len); |
|
276 |
- uri_string[uri.len] = (char)0; |
|
277 | 269 |
ruri = msg->first_line.u.request.uri; |
278 | 270 |
if (ruri.len > MAX_URI_SIZE) { |
279 | 271 |
LM_ERR("message has Request URI too large\n"); |
... | ... |
@@ -288,15 +280,18 @@ int match_hash_table(struct trusted_list** table, struct sip_msg* msg, |
288 | 280 |
(strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && |
289 | 281 |
((np->proto == PROTO_NONE) || (proto == PROTO_NONE) || |
290 | 282 |
(np->proto == proto))) { |
283 |
+ |
|
284 |
+ LM_DBG("match_hash_table: %d, %s, %s, %s\n", np->proto, (np->pattern ? np->pattern : "null"), (np->ruri_pattern ? np->ruri_pattern : "null"), (np->tag.s ? np->tag.s : "null")); |
|
285 |
+ |
|
291 | 286 |
if (IS_SIP(msg)) { |
292 | 287 |
if (np->pattern) { |
293 | 288 |
if (regcomp(&preg, np->pattern, REG_NOSUB)) { |
294 | 289 |
LM_ERR("invalid regular expression\n"); |
295 |
- if (!np->ruri_pattern) { |
|
290 |
+ if (!np->pattern) { |
|
296 | 291 |
continue; |
297 | 292 |
} |
298 | 293 |
} |
299 |
- if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { |
|
294 |
+ if (regexec(&preg, uri, 0, (regmatch_t *)0, 0)) { |
|
300 | 295 |
regfree(&preg); |
301 | 296 |
continue; |
302 | 297 |
} |
... | ... |
@@ -327,6 +322,7 @@ int match_hash_table(struct trusted_list** table, struct sip_msg* msg, |
327 | 322 |
count++; |
328 | 323 |
} |
329 | 324 |
} |
325 |
+ |
|
330 | 326 |
if (!count) |
331 | 327 |
return -1; |
332 | 328 |
else |
... | ... |
@@ -85,10 +85,10 @@ int hash_table_insert(struct trusted_list** hash_table, char* src_ip, |
85 | 85 |
|
86 | 86 |
/* |
87 | 87 |
* Check if an entry exists in hash table that has given src_ip and protocol |
88 |
- * value and pattern or ruri_pattern that matches to From URI. |
|
88 |
+ * value and pattern or ruri_pattern that matches to provided URI. |
|
89 | 89 |
*/ |
90 | 90 |
int match_hash_table(struct trusted_list** table, struct sip_msg* msg, |
91 |
- char *scr_ip, int proto); |
|
91 |
+ char *scr_ip, int proto, char *uri); |
|
92 | 92 |
|
93 | 93 |
|
94 | 94 |
/* |
... | ... |
@@ -141,6 +141,8 @@ static cmd_export_t cmds[] = { |
141 | 141 |
ANY_ROUTE}, |
142 | 142 |
{"allow_trusted", (cmd_function)allow_trusted_2, 2, fixup_spve_spve, |
143 | 143 |
fixup_free_spve_spve, ANY_ROUTE}, |
144 |
+ {"allow_trusted", (cmd_function)allow_trusted_3, 3, fixup_spve_all, |
|
145 |
+ fixup_free_spve_all, ANY_ROUTE}, |
|
144 | 146 |
{"allow_uri", (cmd_function)allow_uri, 2, double_fixup, 0, |
145 | 147 |
REQUEST_ROUTE | FAILURE_ROUTE}, |
146 | 148 |
{"allow_address", (cmd_function)w_allow_address, 3, fixup_allow_address, |
... | ... |
@@ -354,16 +354,15 @@ static inline int match_proto(const char *proto_string, int proto_int) |
354 | 354 |
|
355 | 355 |
return 0; |
356 | 356 |
} |
357 |
- |
|
358 | 357 |
/* |
359 | 358 |
* Matches from uri against patterns returned from database. Returns number |
360 | 359 |
* of matches or -1 if none of the patterns match. |
361 | 360 |
*/ |
362 |
-static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
|
361 |
+static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r, char* uri) |
|
363 | 362 |
{ |
364 | 363 |
int i, tag_avp_type; |
365 |
- str uri, ruri; |
|
366 |
- char uri_string[MAX_URI_SIZE+1]; |
|
364 |
+ str ruri; |
|
365 |
+ |
|
367 | 366 |
char ruri_string[MAX_URI_SIZE+1]; |
368 | 367 |
db_row_t* row; |
369 | 368 |
db_val_t* val; |
... | ... |
@@ -372,14 +371,6 @@ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
372 | 371 |
int count = 0; |
373 | 372 |
|
374 | 373 |
if (IS_SIP(msg)) { |
375 |
- if (parse_from_header(msg) < 0) return -1; |
|
376 |
- uri = get_from(msg)->uri; |
|
377 |
- if (uri.len > MAX_URI_SIZE) { |
|
378 |
- LM_ERR("message has From URI too large\n"); |
|
379 |
- return -1; |
|
380 |
- } |
|
381 |
- memcpy(uri_string, uri.s, uri.len); |
|
382 |
- uri_string[uri.len] = (char)0; |
|
383 | 374 |
ruri = msg->first_line.u.request.uri; |
384 | 375 |
if (ruri.len > MAX_URI_SIZE) { |
385 | 376 |
LM_ERR("message has Request URI too large\n"); |
... | ... |
@@ -392,6 +383,8 @@ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
392 | 383 |
|
393 | 384 |
row = RES_ROWS(_r); |
394 | 385 |
|
386 |
+ LM_DBG("match_res: row numbers %d\n", RES_ROW_N(_r)); |
|
387 |
+ |
|
395 | 388 |
for(i = 0; i < RES_ROW_N(_r); i++) { |
396 | 389 |
val = ROW_VALUES(row + i); |
397 | 390 |
if ((ROW_N(row + i) == 4) && |
... | ... |
@@ -404,6 +397,8 @@ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
404 | 397 |
(VAL_NULL(val + 3) || |
405 | 398 |
((VAL_TYPE(val + 3) == DB1_STRING) && !VAL_NULL(val + 3)))) |
406 | 399 |
{ |
400 |
+ LM_DBG("match_res: %s, %s, %s, %s\n", VAL_STRING(val), VAL_STRING(val + 1), VAL_STRING(val + 2), VAL_STRING(val + 3)); |
|
401 |
+ |
|
407 | 402 |
if (IS_SIP(msg)) { |
408 | 403 |
if (!VAL_NULL(val + 1)) { |
409 | 404 |
if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) { |
... | ... |
@@ -412,7 +407,7 @@ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
412 | 407 |
continue; |
413 | 408 |
} |
414 | 409 |
} |
415 |
- if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { |
|
410 |
+ if (regexec(&preg, uri, 0, (regmatch_t *)0, 0)) { |
|
416 | 411 |
regfree(&preg); |
417 | 412 |
continue; |
418 | 413 |
} |
... | ... |
@@ -444,19 +439,17 @@ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) |
444 | 439 |
count++; |
445 | 440 |
} |
446 | 441 |
} |
447 |
- if (!count) |
|
448 |
- return -1; |
|
449 |
- else |
|
450 |
- return count; |
|
451 |
-} |
|
452 | 442 |
|
443 |
+ return (count == 0 ? -1 : count); |
|
444 |
+} |
|
453 | 445 |
|
454 | 446 |
/* |
455 | 447 |
* Checks based on given source IP address and protocol, and From URI |
456 | 448 |
* of request if request can be trusted without authentication. |
457 | 449 |
*/ |
458 |
-int allow_trusted(struct sip_msg* msg, char *src_ip, int proto) |
|
450 |
+int allow_trusted(struct sip_msg* msg, char *src_ip, int proto, char *uri) |
|
459 | 451 |
{ |
452 |
+ LM_DBG("allow_trusted src_ip: %s, proto: %d, uri: %s\n", src_ip, proto, uri); |
|
460 | 453 |
int result; |
461 | 454 |
db1_res_t* res = NULL; |
462 | 455 |
|
... | ... |
@@ -498,11 +491,11 @@ int allow_trusted(struct sip_msg* msg, char *src_ip, int proto) |
498 | 491 |
return -1; |
499 | 492 |
} |
500 | 493 |
|
501 |
- result = match_res(msg, proto, res); |
|
494 |
+ result = match_res(msg, proto, res, uri); |
|
502 | 495 |
perm_dbf.free_result(db_handle, res); |
503 | 496 |
return result; |
504 | 497 |
} else { |
505 |
- return match_hash_table(*hash_table, msg, src_ip, proto); |
|
498 |
+ return match_hash_table(*hash_table, msg, src_ip, proto, uri); |
|
506 | 499 |
} |
507 | 500 |
} |
508 | 501 |
|
... | ... |
@@ -513,16 +506,29 @@ int allow_trusted(struct sip_msg* msg, char *src_ip, int proto) |
513 | 506 |
*/ |
514 | 507 |
int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2) |
515 | 508 |
{ |
516 |
- return allow_trusted(_msg, ip_addr2a(&(_msg->rcv.src_ip)), |
|
517 |
- _msg->rcv.proto); |
|
518 |
-} |
|
509 |
+ str uri; |
|
510 |
+ char uri_string[MAX_URI_SIZE+1]; |
|
511 |
+ |
|
512 |
+ if (IS_SIP(_msg)) { |
|
513 |
+ if (parse_from_header(_msg) < 0) return -1; |
|
514 |
+ uri = get_from(_msg)->uri; |
|
515 |
+ if (uri.len > MAX_URI_SIZE) { |
|
516 |
+ LM_ERR("message has From URI too large\n"); |
|
517 |
+ return -1; |
|
518 |
+ } |
|
519 | 519 |
|
520 |
+ memcpy(uri_string, uri.s, uri.len); |
|
521 |
+ uri_string[uri.len] = (char)0; |
|
522 |
+ } |
|
523 |
+ |
|
524 |
+ return allow_trusted(_msg, ip_addr2a(&(_msg->rcv.src_ip)), _msg->rcv.proto, uri_string); |
|
525 |
+} |
|
520 | 526 |
|
521 | 527 |
/* |
522 | 528 |
* Checks based on source address and protocol given in pvar arguments and |
523 |
- * and requests's From URI, if request can be trusted without authentication. |
|
529 |
+ * provided uri, if request can be trusted without authentication. |
|
524 | 530 |
*/ |
525 |
-int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp) |
|
531 |
+int allow_trusted_1(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp, char *uri_string) |
|
526 | 532 |
{ |
527 | 533 |
str src_ip, proto; |
528 | 534 |
int proto_int; |
... | ... |
@@ -576,12 +582,50 @@ int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp) |
576 | 582 |
goto error; |
577 | 583 |
} |
578 | 584 |
|
579 |
- return allow_trusted(_msg, src_ip.s, proto_int); |
|
585 |
+ return allow_trusted(_msg, src_ip.s, proto_int, uri_string); |
|
580 | 586 |
error: |
581 | 587 |
LM_ERR("unknown protocol %.*s\n", proto.len, proto.s); |
582 | 588 |
return -1; |
583 | 589 |
} |
584 | 590 |
|
591 |
+/* |
|
592 |
+ * Checks based on source address and protocol given in pvar arguments and |
|
593 |
+ * and requests's From URI, if request can be trusted without authentication. |
|
594 |
+ */ |
|
595 |
+int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp) |
|
596 |
+{ |
|
597 |
+ str uri; |
|
598 |
+ char uri_string[MAX_URI_SIZE+1]; |
|
599 |
+ |
|
600 |
+ if (IS_SIP(_msg)) { |
|
601 |
+ if (parse_from_header(_msg) < 0) return -1; |
|
602 |
+ uri = get_from(_msg)->uri; |
|
603 |
+ if (uri.len > MAX_URI_SIZE) { |
|
604 |
+ LM_ERR("message has From URI too large\n"); |
|
605 |
+ return -1; |
|
606 |
+ } |
|
607 |
+ |
|
608 |
+ memcpy(uri_string, uri.s, uri.len); |
|
609 |
+ uri_string[uri.len] = (char)0; |
|
610 |
+ } |
|
611 |
+ |
|
612 |
+ return allow_trusted_1(_msg, _src_ip_sp, _proto_sp, uri_string); |
|
613 |
+} |
|
614 |
+ |
|
615 |
+/* |
|
616 |
+ * Checks based on source address and protocol given in pvar arguments and |
|
617 |
+ * and requests's From URI, if request can be trusted without authentication. |
|
618 |
+ */ |
|
619 |
+int allow_trusted_3(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp, char *_uri) |
|
620 |
+{ |
|
621 |
+ str uri; |
|
622 |
+ if (_uri==NULL || (fixup_get_svalue(_msg, (gparam_p)_uri, &uri) != 0)) { |
|
623 |
+ LM_ERR("uri param does not exist or has no value\n"); |
|
624 |
+ return -1; |
|
625 |
+ } |
|
626 |
+ |
|
627 |
+ return allow_trusted_1(_msg, _src_ip_sp, _proto_sp, uri.s); |
|
628 |
+} |
|
585 | 629 |
|
586 | 630 |
int reload_trusted_table_cmd(void) |
587 | 631 |
{ |
... | ... |
@@ -75,6 +75,11 @@ int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2); |
75 | 75 |
*/ |
76 | 76 |
int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp); |
77 | 77 |
|
78 |
+/* |
|
79 |
+ * Checks based on source address and protocol given in pvar arguments and |
|
80 |
+ * provided URI, if request can be trusted without authentication. |
|
81 |
+ */ |
|
82 |
+int allow_trusted_3(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp, char* uri); |
|
78 | 83 |
|
79 | 84 |
int reload_trusted_table_cmd(void); |
80 | 85 |
|