-----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; }