-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
is it possible to add a way to userblacklist so that we have two tables (one for incomming and one for outgoing (user|global)blacklists) ?
I enhanced userblacklist module following the sledge hammer method (just duplicating the code) so I have now a 2nd userblacklist table which can be requested by my own check_user_blacklist2() function controlled by 2 additional modparams (use_domain2, db_table2)
It would be nice to have one check_blacklist function with a tablename as an additional parameter.
Or is it designed for using in two separate proxies (one incomming and one outgoing proxy)?
regards Helmut
On Tuesday 15 April 2008, Helmut Kuper wrote:
is it possible to add a way to userblacklist so that we have two tables (one for incomming and one for outgoing (user|global)blacklists) ?
Hi Helmut,
yes, this could be possible. The actual logic is although not designed to this case, for example table version checks are done during the startup.
For the global blacklists (check_blacklist function) nothing needs to be done, this works out of the box, as you specify the table name in the function.
I enhanced userblacklist module following the sledge hammer method (just duplicating the code) so I have now a 2nd userblacklist table which can be requested by my own check_user_blacklist2() function controlled by 2 additional modparams (use_domain2, db_table2)
It would be nice to have one check_blacklist function with a tablename as an additional parameter.
For the user blacklists (check_user_blacklist function) there could be one more parameter for the table added. This parameter should be optional.
check_user_blacklist (string user, string domain, table)
Cheers,
Henning
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi Henning,
so this is a confirmation from you for coding the enhancement? ;)
regards Helmut
[...] | For the user blacklists (check_user_blacklist function) there could be one | more parameter for the table added. This parameter should be optional. | | check_user_blacklist (string user, string domain, table) | | Cheers, | | Henning | |
On Wednesday 16 April 2008, Helmut Kuper wrote:
so this is a confirmation from you for coding the enhancement? ;)
Hi Helmut,
well.. not exactly. ;-) I've not that much time for enhancements like this at the moment, unfortunally. I thought that you perhaps want to contribute a patch. ;-)
Cheers,
Henning
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hello,
I enhanced userblacklist module in that way, that check_user_blacklist function has now 2 additional, but optional, parameters:
check_user_blacklist(string user, string domain [, string number_to_check][, string table])
Purpose of all this is to have serveral user individual blacklists for e.g. incoming and outgoing calls. You have to create one table for each userblacklist in your database. Table layout is same as default "userblacklist" table. Whitelist is the same for all userblacklists supported. Global blacklist behaviour was not touched by this work.
The new behaviour is like this:
number_to-check must be a PV or empty table must be a PV or string
Modparams "use_domain" and "db_url" are global for all userblacklist tables. Modparam "db_table" is default value if no table parameter was given.
a) check_user_blacklist(string user, string domain) or check_user_blacklist(string user, string domain [, "", ""])
behaves as known.
b) check_user_blacklist(string user, string domain, string number_to_check) or check_user_blacklist(string user, string domain, string number_to_check, "")
checks number_to_check against user's prefix using table given in mod_param dt_table.
c) check_user_blacklist(string user, string domain, string number_to_check, string table)
checks number_to_check against user's prefix using given table instead of default mod_param db_table.
d) check_user_blacklist(string user, string domain, "", string table)
checks R-URI against user's prefix using given table instead of mod_param db_table.
Additionally I fixed a potential seg fault caused by strncpy without using MAXNUMBERLEN to protect target buffer in function "check_user_blacklist".
Further e164 numbers (leading '+' sign) as number_to_check or in R-URI are now allowed. "+" is stripped off in function "check_user_blacklist" befor calling dt_longest_match().
Is there a chance to get this into trunk?
regards Helmut
69c69 < static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2); ---
static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2, char* str3, char* str4);
83a84,85
{ "check_user_blacklist", (cmd_function)check_user_blacklist, 3, check_user_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE }, { "check_user_blacklist", (cmd_function)check_user_blacklist, 4, check_user_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE },
148,149c150,151 < model=NULL; < if (param_no==1 || param_no==2) { ---
if (param_no>0 && param_no<=4 && s.len>0) {
155c157,158 < if(pv_parse_format(&s, &model) < 0 || !model) { ---
if(pv_parse_format(&s, &model) < 0 || !model) {
159,161c162,168 < if(!model->spec.getf) { < if(param_no == 1) { < if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n) != 0) { ---
if(!model->spec.getf) { if(param_no == 1) { if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n) != 0) {
164c171,181 < } ---
} } else if(param_no == 3) { LM_ERR("wrong value [%s] for param no %d!\n", s.s, param_no); return E_UNSPEC; } else if(param_no == 4) { LM_DBG("PARAM4 is just a string!\n"); return 0;
166a184
174c192 < static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2) ---
static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2, char* str3, char* str4)
177a196,198
str table = { .len = 0, .s = NULL}; str number = { .len = 0, .s = NULL};
179a201,204
char *ptr;
/* We use strncpy with MAXNUMBERLEN set leter here, so we can terminate string buffer here with \0 */ req_number[MAXNUMBERLEN] = '\0';
186a212
193a220,250
/*Parameter 4=tablename (string or PV)*/ if(str4!=NULL && ((pv_elem_p)str4)->spec.getf) { if(pv_printf_s(msg, (pv_elem_p)str4, &table) != 0) { LM_ERR("cannot print table pseudo-variable\n"); return -1; } } else if(str4!=NULL && strlen(str4)>0) { /*string*/ table.s=str4; table.len=strlen(str4); } else { /*no, then use default table name*/ table.len=db_table.len; table.s=db_table.s; }
/*Source number*/ if(str3!=NULL && ((pv_elem_p)str3)->spec.getf) { if(pv_printf_s(msg, (pv_elem_p)str3, &number) != 0) { LM_ERR("cannot print number pseudo-variable\n"); return -1; } }
198,200c255,268 < if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { < LM_ERR("cannot parse msg URI\n"); < return -1; ---
/* Is number for cheking as parameter given?*/ if(number.s==NULL) { /*No, so use R-URI*/ if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); return -1; }
/*String terminating \0 is set automatically when user.s is shorter than MAXNUMBERLEN*/ strncpy(req_number, msg->parsed_uri.user.s, MAXNUMBERLEN);
202,203c270,271 < strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); < req_number[msg->parsed_uri.user.len] = '\0'; ---
/*String terminating \0 was set at the beginning of this function */ else strncpy(req_number, number.s, MAXNUMBERLEN);
206c274,276 < if (db_build_userbl_tree(&user, &domain, &db_table, dt_root, use_domain) < 0) { ---
LM_DBG("using parameter: '%s', '%s', '%s', '%s'\n", user.s, domain.s, req_number, table.s);
if (db_build_userbl_tree(&user, &domain, &table, dt_root, use_domain) < 0) {
211c281,286 < if (dt_longest_match(dt_root, req_number, &whitelist) >= 0) { ---
/*Checking for e164 numbers. If + is found, remove it*/ if(strlen(req_number)>1 && req_number[0]=='+') ptr=req_number+1; else ptr=req_number;
if (dt_longest_match(dt_root, ptr, &whitelist) >= 0) {
464c539 < LM_INFO("initializing"); ---
LM_INFO("initializing ...\n");
472c547 < LM_INFO("finished initializing"); ---
LM_INFO("finished initializing\n");
On Tuesday 22 April 2008, Helmut Kuper wrote:
I enhanced userblacklist module in that way, that check_user_blacklist function has now 2 additional, but optional, parameters:
check_user_blacklist(string user, string domain [, string number_to_check][, string table])
Purpose of all this is to have serveral user individual blacklists for e.g. incoming and outgoing calls. You have to create one table for each userblacklist in your database. Table layout is same as default "userblacklist" table. Whitelist is the same for all userblacklists supported. Global blacklist behaviour was not touched by this work.
Hi Helmut,
thank you for the patch!
[..] b) check_user_blacklist(string user, string domain, string number_to_check) or check_user_blacklist(string user, string domain, string number_to_check, "")
checks number_to_check against user's prefix using table given in mod_param dt_table.
Looks good. Perhaps it makes sense to make the 'number' parameter mandatory, as the "old" behaviour could be easily achieved with '$ru'. This is perhaps easier to understand.
Additionally I fixed a potential seg fault caused by strncpy without using MAXNUMBERLEN to protect target buffer in function "check_user_blacklist".
Further e164 numbers (leading '+' sign) as number_to_check or in R-URI are now allowed. "+" is stripped off in function "check_user_blacklist" befor calling dt_longest_match().
Good catch.
Is there a chance to get this into trunk?
Can you perhaps send me the patch in unified format (either svn diff or patch -u)? I've tried to apply this patch, but without luck.
Cheers,
Henning
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi Henning,
ok param 3 (number) is now mandatory.
Param 3 was optional because I thought it would be better to keep old syntax instead of forcing existing openser-configurations to be reconfigured...
Param 4 is still optional.
I attached a svn diff as requested.
regards helmut
Henning Westerholt schrieb: | On Tuesday 22 April 2008, Helmut Kuper wrote: |> I enhanced userblacklist module in that way, that check_user_blacklist |> function has now 2 additional, but optional, parameters: |> |> check_user_blacklist(string user, string domain [, string |> number_to_check][, string table]) |> |> Purpose of all this is to have serveral user individual blacklists for |> e.g. incoming and outgoing calls. You have to create one table for each |> userblacklist in your database. Table layout is same as default |> "userblacklist" table. Whitelist is the same for all userblacklists |> supported. Global blacklist behaviour was not touched by this work. | | Hi Helmut, | | thank you for the patch! | |> [..] |> b) check_user_blacklist(string user, string domain, string |> number_to_check) or check_user_blacklist(string user, string domain, |> string number_to_check, "") |> |> checks number_to_check against user's prefix using table given in |> mod_param dt_table. | | Looks good. Perhaps it makes sense to make the 'number' parameter mandatory, | as the "old" behaviour could be easily achieved with '$ru'. This is perhaps | easier to understand. | |> Additionally I fixed a potential seg fault caused by strncpy without |> using MAXNUMBERLEN to protect target buffer in function |> "check_user_blacklist". |> |> Further e164 numbers (leading '+' sign) as number_to_check or in R-URI |> are now allowed. "+" is stripped off in function "check_user_blacklist" |> befor calling dt_longest_match(). | | Good catch. | |> Is there a chance to get this into trunk? | | Can you perhaps send me the patch in unified format (either svn diff or | patch -u)? I've tried to apply this patch, but without luck. | | Cheers, | | Henning | |
On Wednesday 23 April 2008, Helmut Kuper wrote:
ok param 3 (number) is now mandatory.
Param 3 was optional because I thought it would be better to keep old syntax instead of forcing existing openser-configurations to be reconfigured...
Thank you Helmut, i'll later take a look. Well, this don't appeared in an (public) stable release so far, so i don't see a strong need to keep the compatibility here.
Henning
On Wednesday 23 April 2008, Henning Westerholt wrote:
ok param 3 (number) is now mandatory.
Param 3 was optional because I thought it would be better to keep old syntax instead of forcing existing openser-configurations to be reconfigured...
Thank you Helmut, i'll later take a look. Well, this don't appeared in an (public) stable release so far, so i don't see a strong need to keep the compatibility here.
Hello Helmut,
i thought a little more about this issue, and i just ported your first patch, without the 'old' interface change. It provides more consistency with the check_blacklist function. Sorry for the double work.
Additionally I fixed a potential seg fault caused by strncpy without using MAXNUMBERLEN to protect target buffer in function "check_user_blacklist".
I don't used your logic (just copy with strncpy up to the MAXNUMBERLEN size), this does much to work for most of the cases, as its fills the string with unneeded zeros. I just use the existing approach, check if the number length is smaller or equal the MAXNUMBERLEN.
Further e164 numbers (leading '+' sign) as number_to_check or in R-URI are now allowed. "+" is stripped off in function "check_user_blacklist" befor calling dt_longest_match().
I just used the same logic that is actually implemented in the carrierroute module. All non-numerical chars in front of the number are skipped.
Please let me know if you see any issues,
Henning
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hello Henning,
Henning Westerholt schrieb:
| Hello Helmut, | | i thought a little more about this issue, and i just ported your first patch, | without the 'old' interface change. It provides more consistency with the | check_blacklist function. Sorry for the double work.
np, that one was just a seconds lasting small hack ;)
| I don't used your logic (just copy with strncpy up to the MAXNUMBERLEN size), | this does much to work for most of the cases, as its fills the string with | unneeded zeros. I just use the existing approach, check if the number length | is smaller or equal the MAXNUMBERLEN.
Ok, I also thought about that way, but using a single strncpy command was to sexy ... ;) In terms of performance your way is faster I think (depending of MAXNUMBERLEN size of course).
~ > I just used the same logic that is actually implemented in the carrierroute | module. All non-numerical chars in front of the number are skipped. | This should work for me as well.
As soon as the patch is applied I will test it.
Thx and regards Helmut
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Errrrrrmmmm, well a bit sleepy today here ... I forgot the attachment;D
...
Hi Henning,
ok param 3 (number) is now mandatory.
Param 3 was optional because I thought it would be better to keep old syntax instead of forcing existing openser-configurations to be reconfigured...
Param 4 is still optional.
I attached a svn diff as requested.
regards helmut
Henning Westerholt schrieb: | On Tuesday 22 April 2008, Helmut Kuper wrote: |> I enhanced userblacklist module in that way, that check_user_blacklist |> function has now 2 additional, but optional, parameters: |> |> check_user_blacklist(string user, string domain [, string |> number_to_check][, string table]) |> |> Purpose of all this is to have serveral user individual blacklists for |> e.g. incoming and outgoing calls. You have to create one table for each |> userblacklist in your database. Table layout is same as default |> "userblacklist" table. Whitelist is the same for all userblacklists |> supported. Global blacklist behaviour was not touched by this work. | | Hi Helmut, | | thank you for the patch! | |> [..] |> b) check_user_blacklist(string user, string domain, string |> number_to_check) or check_user_blacklist(string user, string domain, |> string number_to_check, "") |> |> checks number_to_check against user's prefix using table given in |> mod_param dt_table. | | Looks good. Perhaps it makes sense to make the 'number' parameter mandatory, | as the "old" behaviour could be easily achieved with '$ru'. This is perhaps | easier to understand. | |> Additionally I fixed a potential seg fault caused by strncpy without |> using MAXNUMBERLEN to protect target buffer in function |> "check_user_blacklist". |> |> Further e164 numbers (leading '+' sign) as number_to_check or in R-URI |> are now allowed. "+" is stripped off in function "check_user_blacklist" |> befor calling dt_longest_match(). | | Good catch. | |> Is there a chance to get this into trunk? | | Can you perhaps send me the patch in unified format (either svn diff or | patch -u)? I've tried to apply this patch, but without luck. | | Cheers, | | Henning | |
Index: userblacklist.c =================================================================== --- userblacklist.c (revision 4028) +++ userblacklist.c (working copy) @@ -66,7 +66,7 @@ static int check_user_blacklist_fixup(void** param, int param_no);
/* ---- exported commands: */ -static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2); +static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2, char* str3, char* str4); static int check_blacklist(struct sip_msg *msg, struct check_blacklist_fs_t *arg1, char *unused);
/* ---- module init functions: */ @@ -80,7 +80,8 @@
static cmd_export_t cmds[]={ - { "check_user_blacklist", (cmd_function)check_user_blacklist, 2, check_user_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE }, + { "check_user_blacklist", (cmd_function)check_user_blacklist, 3, check_user_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE }, + { "check_user_blacklist", (cmd_function)check_user_blacklist, 4, check_user_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE }, { "check_blacklist", (cmd_function)check_blacklist, 1, check_blacklist_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE }, { 0, 0, 0, 0, 0, 0} }; @@ -145,25 +146,41 @@ s.s = (char*)*param; s.len = strlen(s.s);
- model=NULL; - if (param_no==1 || param_no==2) { - if(s.len==0) { + if (param_no>0 && param_no<=4) { + + if(s.len==0 && param_no!=4) { LM_ERR("no param %d!\n", param_no); return E_UNSPEC; }
- if(pv_parse_format(&s, &model) < 0 || !model) { + if(pv_parse_format(&s, &model) < 0 || !model) + { LM_ERR("wrong format [%s] for param no %d!\n", s.s, param_no); return E_UNSPEC; } - if(!model->spec.getf) { - if(param_no == 1) { - if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n) != 0) { + + if(!model->spec.getf) + { + if(param_no == 1) + { + if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n) != 0) + { LM_ERR("wrong value [%s] for param no %d!\n", s.s, param_no); return E_UNSPEC; - } + } } + else if(param_no == 3) + { + LM_ERR("wrong value [%s] for param no %d!\n", s.s, param_no); + return E_UNSPEC; + } + else if(param_no == 4) + { + LM_DBG("PARAM4 is just a string!\n"); + return 0; + } } + *param = (void*)model; }
@@ -171,19 +188,27 @@ }
-static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2) +static int check_user_blacklist(struct sip_msg *msg, char* str1, char* str2, char* str3, char* str4) { str user = { .len = 0, .s = NULL }; str domain = { .len = 0, .s = NULL}; + str table = { .len = 0, .s = NULL}; + str number = { .len = 0, .s = NULL}; + char whitelist; char req_number[MAXNUMBERLEN+1]; + char *ptr;
+ /* We use strncpy with MAXNUMBERLEN set leter here, so we can terminate string buffer here with \0 */ + req_number[MAXNUMBERLEN] = '\0'; + if(((pv_elem_p)str1)->spec.getf) { if(pv_printf_s(msg, (pv_elem_p)str1, &user) != 0) { LM_ERR("cannot print user pseudo-variable\n"); return -1; } } + if(((pv_elem_p)str2)->spec.getf) { if(pv_printf_s(msg, (pv_elem_p)str2, &domain) != 0) { @@ -191,24 +216,58 @@ return -1; } } + + /*Parameter 4=tablename (string or PV)*/ + if(str4!=NULL && ((pv_elem_p)str4)->spec.getf) + { + if(pv_printf_s(msg, (pv_elem_p)str4, &table) != 0) { + LM_ERR("cannot print table pseudo-variable\n"); + return -1; + } + } + else if(str4!=NULL && strlen(str4)>0) + { + /*string*/ + table.s=str4; + table.len=strlen(str4); + } + else + { + /*no, then use default table name*/ + table.len=db_table.len; + table.s=db_table.s; + } + + /*Source number*/ + if(str3!=NULL && ((pv_elem_p)str3)->spec.getf) + { + if(pv_printf_s(msg, (pv_elem_p)str3, &number) != 0) { + LM_ERR("cannot print number pseudo-variable\n"); + return -1; + } + } + if (msg->first_line.type != SIP_REQUEST) { LM_ERR("SIP msg is not a request\n"); return -1; } - if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { - LM_ERR("cannot parse msg URI\n"); - return -1; - } - strncpy(req_number, msg->parsed_uri.user.s, msg->parsed_uri.user.len); - req_number[msg->parsed_uri.user.len] = '\0';
+ strncpy(req_number, number.s, MAXNUMBERLEN); + LM_DBG("check entry %s\n", req_number); - if (db_build_userbl_tree(&user, &domain, &db_table, dt_root, use_domain) < 0) { + LM_DBG("using parameter: '%s', '%s', '%s', '%s'\n", user.s, domain.s, req_number, table.s); + + if (db_build_userbl_tree(&user, &domain, &table, dt_root, use_domain) < 0) { LM_ERR("cannot build d-tree\n"); return -1; }
- if (dt_longest_match(dt_root, req_number, &whitelist) >= 0) { + /*Checking for e164 numbers. If + is found, remove it*/ + if(strlen(req_number)>1 && req_number[0]=='+') ptr=req_number+1; + else ptr=req_number; + + if (dt_longest_match(dt_root, ptr, &whitelist) >= 0) + { if (whitelist) { /* LM_ERR("whitelisted"); */ return 1; /* found, but is whitelisted */ @@ -461,7 +520,7 @@
static int mod_init(void) { - LM_INFO("initializing"); + LM_INFO("initializing ...\n"); db_url.len = strlen(db_url.s); db_table.len = strlen(db_table.s);
@@ -469,7 +528,7 @@ if (db_bind(&db_url) != 0) return -1; if (init_shmlock() != 0) return -1; if (init_source_list() != 0) return -1; - LM_INFO("finished initializing"); + LM_INFO("finished initializing\n");
return 0; }