00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039
00040 #include "../../sr_module.h"
00041 #include "../../dprint.h"
00042 #include "../../error.h"
00043 #include "../../pvar.h"
00044 #include "../../pt.h"
00045 #include "../../timer.h"
00046 #include "../../mem/mem.h"
00047 #include "../../parser/parse_from.h"
00048 #include "../../modules/tm/tm_load.h"
00049 #include "../../modules/tm/t_hooks.h"
00050 #include "../../mod_fix.h"
00051 #include "../../rpc.h"
00052 #include "../../rpc_lookup.h"
00053 #include "../../cfg/cfg_struct.h"
00054
00055 #include "../rr/api.h"
00056
00057 #include "replace.h"
00058 #include "auth.h"
00059 #include "uac_send.h"
00060 #include "uac_reg.h"
00061 #include "api.h"
00062
00063
00064 MODULE_VERSION
00065
00066
00067
00068 static char* restore_mode_str = NULL;
00069 static char* auth_username_avp = NULL;
00070 static char* auth_realm_avp = NULL;
00071 static char* auth_password_avp = NULL;
00072 unsigned short restore_from_avp_type;
00073 int_str restore_from_avp_name;
00074 unsigned short restore_to_avp_type;
00075 int_str restore_to_avp_name;
00076
00077
00078 str rr_from_param = str_init("vsf");
00079 str rr_to_param = str_init("vst");
00080 str uac_passwd = str_init("");
00081 str restore_from_avp = {0 ,0 };
00082 str restore_to_avp = {0 ,0 };
00083 int restore_mode = UAC_AUTO_RESTORE;
00084 struct tm_binds uac_tmb;
00085 struct rr_binds uac_rrb;
00086 pv_spec_t auth_username_spec;
00087 pv_spec_t auth_realm_spec;
00088 pv_spec_t auth_password_spec;
00089
00090 static int w_replace_from(struct sip_msg* msg, char* p1, char* p2);
00091 static int w_restore_from(struct sip_msg* msg);
00092 static int w_replace_to(struct sip_msg* msg, char* p1, char* p2);
00093 static int w_restore_to(struct sip_msg* msg);
00094 static int w_uac_auth(struct sip_msg* msg, char* str, char* str2);
00095 static int w_uac_reg_lookup(struct sip_msg* msg, char* src, char* dst);
00096 static int w_uac_reg_request_to(struct sip_msg* msg, char* src, char* mode_s);
00097 static int fixup_replace_uri(void** param, int param_no);
00098 static int fixup_replace_disp_uri(void** param, int param_no);
00099 static int mod_init(void);
00100 static void mod_destroy(void);
00101 static int child_init(int rank);
00102
00103 extern int reg_timer_interval;
00104
00105 static pv_export_t mod_pvs[] = {
00106 { {"uac_req", sizeof("uac_req")-1}, PVT_OTHER, pv_get_uac_req, pv_set_uac_req,
00107 pv_parse_uac_req_name, 0, 0, 0 },
00108 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00109 };
00110
00111
00112
00113 static cmd_export_t cmds[]={
00114 {"uac_replace_from", (cmd_function)w_replace_from, 2, fixup_replace_disp_uri, 0,
00115 REQUEST_ROUTE | BRANCH_ROUTE },
00116 {"uac_replace_from", (cmd_function)w_replace_from, 1, fixup_replace_uri, 0,
00117 REQUEST_ROUTE | BRANCH_ROUTE },
00118 {"uac_restore_from", (cmd_function)w_restore_from, 0, 0, 0,
00119 REQUEST_ROUTE },
00120 {"uac_replace_to", (cmd_function)w_replace_to, 2, fixup_replace_disp_uri, 0,
00121 REQUEST_ROUTE | BRANCH_ROUTE },
00122 {"uac_replace_to", (cmd_function)w_replace_to, 1, fixup_replace_uri, 0,
00123 REQUEST_ROUTE | BRANCH_ROUTE },
00124 {"uac_restore_to", (cmd_function)w_restore_to, 0, 0, 0,
00125 REQUEST_ROUTE },
00126 {"uac_auth", (cmd_function)w_uac_auth, 0, 0, 0,
00127 FAILURE_ROUTE },
00128 {"uac_req_send", (cmd_function)uac_req_send, 0, 0, 0,
00129 REQUEST_ROUTE | FAILURE_ROUTE |
00130 ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
00131 {"uac_reg_lookup", (cmd_function)w_uac_reg_lookup, 2, fixup_pvar_pvar,
00132 fixup_free_pvar_pvar, ANY_ROUTE },
00133 {"uac_reg_request_to", (cmd_function)w_uac_reg_request_to, 2, fixup_pvar_uint, fixup_free_pvar_uint,
00134 REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE },
00135 {"bind_uac", (cmd_function)bind_uac, 1, 0, 0,
00136 0},
00137 {0,0,0,0,0,0}
00138 };
00139
00140
00141
00142
00143 static param_export_t params[] = {
00144 {"rr_from_store_param", STR_PARAM, &rr_from_param.s },
00145 {"rr_to_store_param", STR_PARAM, &rr_to_param.s },
00146 {"restore_mode", STR_PARAM, &restore_mode_str },
00147 {"restore_passwd", STR_PARAM, &uac_passwd.s },
00148 {"restore_from_avp", STR_PARAM, &restore_from_avp.s },
00149 {"restore_to_avp", STR_PARAM, &restore_to_avp.s },
00150 {"credential", STR_PARAM|USE_FUNC_PARAM, (void*)&add_credential },
00151 {"auth_username_avp", STR_PARAM, &auth_username_avp },
00152 {"auth_realm_avp", STR_PARAM, &auth_realm_avp },
00153 {"auth_password_avp", STR_PARAM, &auth_password_avp },
00154 {"reg_db_url", STR_PARAM, ®_db_url.s },
00155 {"reg_contact_addr", STR_PARAM, ®_contact_addr.s },
00156 {"reg_timer_interval", INT_PARAM, ®_timer_interval },
00157 {0, 0, 0}
00158 };
00159
00160
00161
00162 struct module_exports exports= {
00163 "uac",
00164 DEFAULT_DLFLAGS,
00165 cmds,
00166 params,
00167 0,
00168 0,
00169 mod_pvs,
00170 0,
00171 mod_init,
00172 0,
00173 mod_destroy,
00174 child_init
00175 };
00176
00177
00178 inline static int parse_auth_avp( char *avp_spec, pv_spec_t *avp, char *txt)
00179 {
00180 str s;
00181 s.s = avp_spec; s.len = strlen(s.s);
00182 if (pv_parse_spec(&s, avp)==NULL) {
00183 LM_ERR("malformed or non AVP %s AVP definition\n",txt);
00184 return -1;
00185 }
00186 return 0;
00187 }
00188
00189
00190 static int mod_init(void)
00191 {
00192 pv_spec_t avp_spec;
00193
00194 if (restore_mode_str && *restore_mode_str) {
00195 if (strcasecmp(restore_mode_str,"none")==0) {
00196 restore_mode = UAC_NO_RESTORE;
00197 } else if (strcasecmp(restore_mode_str,"manual")==0) {
00198 restore_mode = UAC_MANUAL_RESTORE;
00199 } else if (strcasecmp(restore_mode_str,"auto")==0) {
00200 restore_mode = UAC_AUTO_RESTORE;
00201 } else {
00202 LM_ERR("unsupported value '%s' for restore_mode\n", restore_mode_str);
00203 goto error;
00204 }
00205 }
00206
00207 rr_from_param.len = strlen(rr_from_param.s);
00208 rr_to_param.len = strlen(rr_to_param.s);
00209 if ( (rr_from_param.len==0 || rr_to_param.len==0) && restore_mode!=UAC_NO_RESTORE)
00210 {
00211 LM_ERR("rr_store_param cannot be empty if FROM is restoreable\n");
00212 goto error;
00213 }
00214
00215 uac_passwd.len = strlen(uac_passwd.s);
00216
00217
00218 if ( auth_username_avp || auth_password_avp || auth_realm_avp) {
00219 if (!auth_username_avp || !auth_password_avp || !auth_realm_avp) {
00220 LM_ERR("partial definition of auth AVP!");
00221 goto error;
00222 }
00223 if ( parse_auth_avp(auth_realm_avp, &auth_realm_spec, "realm")<0
00224 || parse_auth_avp(auth_username_avp, &auth_username_spec, "username")<0
00225 || parse_auth_avp(auth_password_avp, &auth_password_spec, "password")<0
00226 ) {
00227 goto error;
00228 }
00229 } else {
00230 memset( &auth_realm_spec, 0, sizeof(pv_spec_t));
00231 memset( &auth_password_spec, 0, sizeof(pv_spec_t));
00232 memset( &auth_username_spec, 0, sizeof(pv_spec_t));
00233 }
00234
00235
00236
00237 if (load_tm_api(&uac_tmb)!=0) {
00238 LM_ERR("can't load TM API\n");
00239 goto error;
00240 }
00241
00242 if (restore_mode!=UAC_NO_RESTORE) {
00243
00244 if (load_rr_api(&uac_rrb)!=0) {
00245 LM_ERR("can't load RR API\n");
00246 goto error;
00247 }
00248
00249
00250 if(restore_from_avp.s) {
00251
00252 restore_from_avp.len = strlen(restore_from_avp.s);
00253
00254 if (pv_parse_spec(&restore_from_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
00255 LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_from_avp.len, restore_from_avp.s);
00256 return -1;
00257 }
00258
00259 if(pv_get_avp_name(0, &avp_spec.pvp, &restore_from_avp_name, &restore_from_avp_type)!=0) {
00260 LM_ERR("[%.*s]- invalid AVP definition\n", restore_from_avp.len, restore_from_avp.s);
00261 return -1;
00262 }
00263
00264 restore_from_avp_type |= AVP_VAL_STR;
00265
00266 }
00267
00268 if(restore_to_avp.s) {
00269
00270 restore_to_avp.len = strlen(restore_to_avp.s);
00271
00272 if (pv_parse_spec(&restore_to_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
00273 LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_to_avp.len, restore_to_avp.s);
00274 return -1;
00275 }
00276
00277 if(pv_get_avp_name(0, &avp_spec.pvp, &restore_to_avp_name, &restore_to_avp_type)!=0) {
00278 LM_ERR("[%.*s]- invalid AVP definition\n", restore_to_avp.len, restore_to_avp.s);
00279 return -1;
00280 }
00281
00282 restore_to_avp_type |= AVP_VAL_STR;
00283
00284 }
00285
00286
00287 if (restore_mode==UAC_AUTO_RESTORE) {
00288
00289 if (!uac_rrb.append_fromtag) {
00290 LM_ERR("'append_fromtag' RR param is not enabled"
00291 " - required by AUTO restore mode!"
00292 " Or you should set from_restore_mode param to 'none'\n");
00293 goto error;
00294 }
00295
00296 if (uac_rrb.register_rrcb( rr_checker, 0)!=0) {
00297 LM_ERR("failed to install RR callback\n");
00298 goto error;
00299 }
00300 }
00301 }
00302
00303 if(reg_db_url.s!=NULL)
00304 {
00305 if(reg_contact_addr.s==NULL)
00306 {
00307 LM_ERR("contact address parameter not set\n");
00308 goto error;
00309 }
00310 if(reg_htable_size>14)
00311 reg_htable_size = 14;
00312 if(reg_htable_size<2)
00313 reg_htable_size = 2;
00314
00315 reg_htable_size = 1<<reg_htable_size;
00316 if(uac_reg_init_rpc()!=0)
00317 {
00318 LM_ERR("failed to register RPC commands\n");
00319 goto error;
00320 }
00321 if(uac_reg_init_ht(reg_htable_size)<0)
00322 {
00323 LM_ERR("failed to init reg htable\n");
00324 goto error;
00325 }
00326 uac_reg_init_db();
00327 register_procs(1);
00328
00329 cfg_register_child(1);
00330 }
00331 init_from_replacer();
00332
00333 uac_req_init();
00334
00335 return 0;
00336 error:
00337 return -1;
00338 }
00339
00340 static int child_init(int rank)
00341 {
00342 int pid;
00343 if (rank!=PROC_MAIN)
00344 return 0;
00345
00346 if(reg_db_url.s==NULL)
00347 return 0;
00348
00349 pid=fork_process(PROC_TIMER, "TIMER UAC REG", 1);
00350 if (pid<0)
00351 {
00352 LM_ERR("failed to register timer routine as process\n");
00353 return -1;
00354 }
00355 if (pid==0){
00356
00357
00358 if (cfg_child_init())
00359 return -1;
00360
00361 uac_reg_load_db();
00362 uac_reg_timer(0);
00363 for(;;){
00364
00365 cfg_update();
00366
00367 sleep(reg_timer_interval);
00368 uac_reg_timer(get_ticks());
00369 }
00370 }
00371
00372 return 0;
00373 }
00374
00375 static void mod_destroy(void)
00376 {
00377 destroy_credentials();
00378 }
00379
00380
00381
00382
00383
00384 static int fixup_replace_uri(void** param, int param_no)
00385 {
00386 pv_elem_t *model;
00387 str s;
00388
00389 model=NULL;
00390 s.s = (char*)(*param); s.len = strlen(s.s);
00391 if(pv_parse_format(&s, &model)<0)
00392 {
00393 LM_ERR("wrong format[%s]!\n",(char*)(*param));
00394 return E_UNSPEC;
00395 }
00396 if (model==NULL)
00397 {
00398 LM_ERR("empty parameter!\n");
00399 return E_UNSPEC;
00400 }
00401 *param = (void*)model;
00402
00403 return 0;
00404 }
00405
00406
00407 static int fixup_replace_disp_uri(void** param, int param_no)
00408 {
00409 pv_elem_t *model;
00410 char *p;
00411 str s;
00412
00413
00414 s.s = (char*)*param;
00415 s.len = strlen(s.s);
00416
00417 model=NULL;
00418 if (param_no==1)
00419 {
00420 if (s.len)
00421 {
00422
00423 p = (char*)pkg_malloc(s.len+3);
00424 if (p==0)
00425 {
00426 LM_CRIT("no more pkg mem\n");
00427 return E_OUT_OF_MEM;
00428 }
00429 p[0] = '\"';
00430 memcpy(p+1, s.s, s.len);
00431 p[s.len+1] = '\"';
00432 p[s.len+2] = '\0';
00433 pkg_free(s.s);
00434 s.s = p;
00435 s.len += 2;
00436 }
00437 }
00438 if(s.len!=0)
00439 {
00440 if(pv_parse_format(&s ,&model)<0)
00441 {
00442 LM_ERR("wrong format [%s] for param no %d!\n", s.s, param_no);
00443 pkg_free(s.s);
00444 return E_UNSPEC;
00445 }
00446 }
00447 *param = (void*)model;
00448
00449 return 0;
00450 }
00451
00452
00453
00454
00455
00456 static int w_restore_from(struct sip_msg *msg)
00457 {
00458
00459 if (msg->first_line.type!=SIP_REQUEST) {
00460 LM_ERR("called for something not request\n");
00461 return -1;
00462 }
00463
00464 return (restore_uri(msg,&rr_from_param,&restore_from_avp,1)==0)?1:-1;
00465 }
00466
00467
00468 int w_replace_from(struct sip_msg* msg, char* p1, char* p2)
00469 {
00470 str uri_s;
00471 str dsp_s;
00472 str *uri;
00473 str *dsp;
00474
00475 if (p2==NULL) {
00476 p2 = p1;
00477 p1 = NULL;
00478 dsp = NULL;
00479 }
00480
00481
00482
00483 if ( p1!=NULL ) {
00484 if(pv_printf_s( msg, (pv_elem_p)p1, &dsp_s)!=0)
00485 return -1;
00486 dsp = &dsp_s;
00487 }
00488
00489
00490 if (pv_printf_s( msg, (pv_elem_p)p2, &uri_s)!=0)
00491 return -1;
00492 uri = uri_s.len?&uri_s:NULL;
00493
00494 if (parse_from_header(msg)<0 ) {
00495 LM_ERR("failed to find/parse FROM hdr\n");
00496 return -1;
00497 }
00498
00499 LM_DBG("dsp=%p (len=%d) , uri=%p (len=%d)\n",dsp,dsp?dsp->len:0,uri,uri?uri->len:0);
00500
00501 return (replace_uri(msg, dsp, uri, msg->from, &rr_from_param, &restore_from_avp, 1)==0)?1:-1;
00502
00503 }
00504
00505 int replace_from_api(sip_msg_t *msg, str* pd, str* pu)
00506 {
00507 str *uri;
00508 str *dsp;
00509 if (parse_from_header(msg)<0 ) {
00510 LM_ERR("failed to find/parse FROM hdr\n");
00511 return -1;
00512 }
00513
00514 uri = (pu!=NULL && pu->len>0)?pu:NULL;
00515 dsp = (pd!=NULL && pd->len>0)?pd:NULL;
00516
00517 LM_DBG("dsp=%p (len=%d) , uri=%p (len=%d)\n", dsp, dsp?dsp->len:0,
00518 uri, uri?uri->len:0);
00519
00520 return replace_uri(msg, dsp, uri, msg->from, &rr_from_param, &restore_from_avp, 1);
00521 }
00522
00523 static int w_restore_to(struct sip_msg *msg)
00524 {
00525
00526 if (msg->first_line.type!=SIP_REQUEST) {
00527 LM_ERR("called for something not request\n");
00528 return -1;
00529 }
00530
00531 return (restore_uri(msg,&rr_to_param,&restore_to_avp,0)==0)?1:-1;
00532 }
00533
00534
00535 static int w_replace_to(struct sip_msg* msg, char* p1, char* p2)
00536 {
00537 str uri_s;
00538 str dsp_s;
00539 str *uri;
00540 str *dsp;
00541
00542 if (p2==NULL) {
00543 p2 = p1;
00544 p1 = NULL;
00545 dsp = NULL;
00546 }
00547
00548
00549
00550 if( p1!=NULL ) {
00551 if(pv_printf_s( msg, (pv_elem_p)p1, &dsp_s)!=0)
00552 return -1;
00553 dsp = &dsp_s;
00554 }
00555
00556
00557 if (pv_printf_s( msg, (pv_elem_p)p2, &uri_s)!=0)
00558 return -1;
00559 uri = uri_s.len?&uri_s:NULL;
00560
00561
00562 if ( msg->to==0 && (parse_headers(msg,HDR_TO_F,0)!=0 || msg->to==0) ) {
00563 LM_ERR("failed to parse TO hdr\n");
00564 return -1;
00565 }
00566
00567 return (replace_uri(msg, dsp, uri, msg->to, &rr_to_param, &restore_to_avp, 0)==0)?1:-1;
00568
00569 }
00570
00571
00572 static int w_uac_auth(struct sip_msg* msg, char* str, char* str2)
00573 {
00574 return (uac_auth(msg)==0)?1:-1;
00575 }
00576
00577
00578 static int w_uac_reg_lookup(struct sip_msg* msg, char* src, char* dst)
00579 {
00580 pv_spec_t *spv;
00581 pv_spec_t *dpv;
00582 pv_value_t val;
00583
00584 spv = (pv_spec_t*)src;
00585 dpv = (pv_spec_t*)dst;
00586 if(pv_get_spec_value(msg, spv, &val) != 0)
00587 {
00588 LM_ERR("cannot get src uri value\n");
00589 return -1;
00590 }
00591
00592 if (!(val.flags & PV_VAL_STR))
00593 {
00594 LM_ERR("src pv value is not string\n");
00595 return -1;
00596 }
00597 return uac_reg_lookup(msg, &val.rs, dpv, 0);
00598 }
00599
00600
00601 static int w_uac_reg_request_to(struct sip_msg* msg, char* src, char* mode_s)
00602 {
00603 pv_spec_t *spv;
00604 pv_value_t val;
00605 unsigned int mode;
00606
00607 mode = (unsigned int)(long)mode_s;
00608
00609 spv = (pv_spec_t*)src;
00610 if(pv_get_spec_value(msg, spv, &val) != 0)
00611 {
00612 LM_ERR("cannot get src uri value\n");
00613 return -1;
00614 }
00615
00616 if (!(val.flags & PV_VAL_STR))
00617 {
00618 LM_ERR("src pv value is not string\n");
00619 return -1;
00620 }
00621
00622 if (mode > 1)
00623 {
00624 LM_ERR("invalid mode\n");
00625 return -1;
00626 }
00627
00628 return uac_reg_request_to(msg, &val.rs, mode);
00629 }
00630
00631
00632 int bind_uac(struct uac_binds *uacb)
00633 {
00634 if (uacb == NULL)
00635 {
00636 LM_WARN("bind_uac: Cannot load uac API into a NULL pointer\n");
00637 return -1;
00638 }
00639
00640 uacb->replace_from = replace_from_api;
00641 return 0;
00642 }