00001
00058 #include "sip.h"
00059
00060 #include "../../mem/mem.h"
00061 #include "../../data_lump.h"
00062 #include "../../data_lump_rpl.h"
00063 #include "../../parser/parse_to.h"
00064 #include "../../parser/parse_from.h"
00065 #include "../../parser/parse_expires.h"
00066 #include "../../parser/parse_via.h"
00067 #include "../../parser/parse_content.h"
00068 #include "../../parser/parse_nameaddr.h"
00069 #include "../../parser/contact/contact.h"
00070 #include "../../parser/contact/parse_contact.h"
00071
00072 #include "../tm/tm_load.h"
00073
00074 #include "mod.h"
00075 #include "auth_api.h"
00076
00077 #define strtotime(src,dest) \
00078 {\
00079 int i;\
00080 (dest)=0;\
00081 for(i=0;i<(src).len;i++)\
00082 if ((src).s[i]>='0' && (src).s[i]<='9')\
00083 (dest) = (dest)*10 + (src).s[i] -'0';\
00084 }
00085
00086
00087 #define get_qparam(src,name,dst) \
00088 {\
00089 int i,j;\
00090 (dst).s=0;(dst).len=0;\
00091 for(i=0;i<(src).len-(name).len;i++)\
00092 if (strncasecmp((src).s+i,(name).s,(name).len)==0){\
00093 j=i+(name).len;\
00094 (dst).s = (src).s+j;\
00095 (dst).len = 0;\
00096 while(j<(src).len && (src).s[j]!='\"') \
00097 j++; \
00098 (dst).len = j-i-(name).len;\
00099 break;\
00100 } \
00101 }
00102
00103 #define get_param(src,name,dst) \
00104 {\
00105 int i,j;\
00106 (dst).s=0;(dst).len=0;\
00107 for(i=0;i<(src).len-(name).len;i++)\
00108 if (strncasecmp((src).s+i,(name).s,(name).len)==0 &&\
00109 ((src).s[i-1]==' ' ||(src).s[i-1]==';'||(src).s[i-1]=='\t')){\
00110 j=i+(name).len;\
00111 (dst).s = (src).s+j;\
00112 (dst).len = 0;\
00113 while(j<(src).len && (src).s[j]!=','&& (src).s[j]!=' '&& (src).s[j]!='\t'&& (src).s[j]!=';') \
00114 j++; \
00115 (dst).len = j-i-(name).len;\
00116 break;\
00117 } \
00118 }
00119
00120 extern struct tm_binds tmb;
00128 int cscf_add_header_first(struct sip_msg *msg, str *hdr,int type)
00129 {
00130 struct hdr_field *first;
00131 struct lump* anchor,*l;
00132
00133 first = msg->headers;
00134 anchor = anchor_lump(msg, first->name.s - msg->buf, 0 , 0 );
00135
00136 if (anchor == NULL) {
00137 LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: anchor_lump failed\n");
00138 return 0;
00139 }
00140
00141 if (!(l=insert_new_lump_before(anchor, hdr->s,hdr->len,type))){
00142 LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: error creating lump for header\n" );
00143 return 0;
00144 }
00145 return 1;
00146 }
00147
00154 int cscf_add_header(struct sip_msg *msg, str *hdr,int type)
00155 {
00156 struct hdr_field *last;
00157 struct lump* anchor;
00158 last = msg->headers;
00159 while(last->next)
00160 last = last->next;
00161 anchor = anchor_lump(msg, last->name.s + last->len - msg->buf, 0 , 0);
00162 if (anchor == NULL) {
00163 LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: anchor_lump failed\n");
00164 return 0;
00165 }
00166
00167 if (!insert_new_lump_after(anchor, hdr->s,hdr->len,type)){
00168 LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_first: error creting lump for header\n" );
00169 return 0;
00170 }
00171 return 1;
00172 }
00173
00180 int cscf_add_header_rpl(struct sip_msg *msg, str *hdr)
00181 {
00182 if (add_lump_rpl( msg, hdr->s, hdr->len, LUMP_RPL_HDR)==0) {
00183 LOG(L_ERR, "ERR:"M_NAME":cscf_add_header_rpl: Can't add header <%.*s>\n",
00184 hdr->len,hdr->s);
00185 return 0;
00186 }
00187 return 1;
00188 }
00189
00190
00191
00200 str cscf_get_private_identity(struct sip_msg *msg, str realm)
00201 {
00202 str pi={0,0};
00203 struct hdr_field* h=0;
00204 int ret,i;
00205
00206 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00207 LOG(L_ERR,"ERR:"M_NAME":cscf_get_private_identity: Error parsing until header Authorization: \n");
00208 return pi;
00209 }
00210
00211 if (!msg->authorization){
00212 LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: Message does not contain Authorization header.\n");
00213 goto fallback;
00214 }
00215
00216 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00217 if (ret < 0) {
00218 LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: Error while looking for credentials.\n");
00219 goto fallback;
00220 } else
00221 if (ret > 0) {
00222 LOG(L_ERR, "ERR:"M_NAME":cscf_get_private_identity: No credentials for this realm found.\n");
00223 goto fallback;
00224 }
00225
00226 if (h) pi=((auth_body_t*)h->parsed)->digest.username.whole;
00227
00228 goto done;
00229
00230 fallback:
00231 LOG(L_INFO,"INF:"M_NAME":cscf_get_private_identity: Falling back to private_id=stripped(public_id)\n"
00232 "-> Message did not contain a valid Authorization Header!!! This fallback is deprecated outside Early-IMS or NASS-Bundled!\n");
00233 pi = cscf_get_public_identity(msg);
00234 if (pi.len>4&&strncasecmp(pi.s,"sip:",4)==0) {pi.s+=4;pi.len-=4;}
00235 for(i=0;i<pi.len;i++)
00236 if (pi.s[i]==';') {
00237 pi.len=i;
00238 break;
00239 }
00240 done:
00241 LOG(L_DBG,"DBG:"M_NAME":cscf_get_private_identity: <%.*s> \n",
00242 pi.len,pi.s);
00243 return pi;
00244 }
00245
00251 str cscf_get_public_identity(struct sip_msg *msg)
00252 {
00253 str pu={0,0};
00254 struct to_body *to;
00255 int i;
00256
00257 if (parse_headers(msg,HDR_TO_F,0)!=0) {
00258 LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n");
00259 return pu;
00260 }
00261
00262 if ( get_to(msg) == NULL ) {
00263 to = (struct to_body*) pkg_malloc(sizeof(struct to_body));
00264 parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to );
00265 msg->to->parsed = to;
00266 }
00267 else to=(struct to_body *) msg->to->parsed;
00268
00269 pu = to->uri;
00270
00271
00272 for(i=4;i<pu.len;i++)
00273 if (pu.s[i]==';' || pu.s[i]=='?' ||pu.s[i]==':'){
00274 pu.len = i;
00275 }
00276
00277 LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n",
00278 pu.len,pu.s);
00279 return pu;
00280 }
00281
00282
00283
00290 int cscf_get_expires_hdr(struct sip_msg *msg)
00291 {
00292 exp_body_t *exp;
00293 int expires;
00294 if (!msg) return -1;
00295
00296 if (parse_headers(msg,HDR_EXPIRES_F,0)!=0) {
00297 LOG(L_ERR,"ERR:"M_NAME":cscf_get_expires_hdr: Error parsing until header EXPIRES: \n");
00298 return -1;
00299 }
00300 if (msg->expires){
00301 if (!msg->expires->parsed) {
00302 parse_expires(msg->expires);
00303 }
00304 if (msg->expires->parsed) {
00305 exp = (exp_body_t*) msg->expires->parsed;
00306 if (exp->valid) {
00307 expires = exp->val;
00308 LOG(L_DBG,"DBG:"M_NAME":cscf_get_expires_hdr: <%d> \n",expires);
00309 return expires;
00310 }
00311 }
00312 }
00313
00314 return -1;
00315 }
00316
00324 int cscf_get_max_expires(struct sip_msg *msg)
00325 {
00326 unsigned int exp;
00327 int max_expires = -1;
00328 struct hdr_field *h;
00329 contact_t *c;
00330
00331 max_expires = cscf_get_expires_hdr(msg);
00332
00333 cscf_parse_contacts(msg);
00334 for(h=msg->contact;h;h=h->next){
00335 if (h->type==HDR_CONTACT_T && h->parsed) {
00336 for(c=((contact_body_t *) h->parsed)->contacts;c;c=c->next){
00337 if(c->expires){
00338 if (!str2int(&(c->expires->body), (unsigned int*)&exp) && (int)exp>max_expires) max_expires = exp;
00339 }
00340 }
00341 }
00342 }
00343 LOG(L_DBG,"DBG:"M_NAME":cscf_get_max_expires: <%d> \n",max_expires);
00344 return max_expires;
00345 }
00346
00352 str cscf_get_public_identity_from_requri(struct sip_msg *msg)
00353 {
00354 str pu={0,0};
00355
00356 if (msg->first_line.type!=SIP_REQUEST) {
00357 LOG(L_ERR,"INF:"M_NAME":cscf_get_public_identity_from_requri: This ain't a request \n");
00358 return pu;
00359 }
00360 if (parse_sip_msg_uri(msg)<0){
00361 LOG(L_ERR,"INF:"M_NAME":cscf_get_public_identity_from_requri: Error parsing requesturi \n");
00362 return pu;
00363 }
00364
00365 if(msg->parsed_uri.type==TEL_URI_T){
00366 pu.len = 4 + msg->parsed_uri.user.len ;
00367 pu.s = shm_malloc(pu.len+1);
00368 sprintf(pu.s,"tel:%.*s",
00369 msg->parsed_uri.user.len,
00370 msg->parsed_uri.user.s);
00371 }else{
00372 pu.len = 4 + msg->parsed_uri.user.len + 1 + msg->parsed_uri.host.len;
00373 pu.s = shm_malloc(pu.len+1);
00374 sprintf(pu.s,"sip:%.*s@%.*s",
00375 msg->parsed_uri.user.len,
00376 msg->parsed_uri.user.s,
00377 msg->parsed_uri.host.len,
00378 msg->parsed_uri.host.s);
00379 }
00380
00381 LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity_from_requri: <%.*s> \n",
00382 pu.len,pu.s);
00383 return pu;
00384 }
00385
00392 struct sip_msg *cscf_get_request(unsigned int hash,unsigned int label)
00393 {
00394 struct cell *c;
00395 if (tmb.t_lookup_ident(&c,hash,label)<0){
00396 LOG(L_INFO,"INF:"M_NAME":Cx_UAA_timeout: No transaction found for %u %u\n",
00397 hash,label);
00398 return 0;
00399 }
00400 return c->uas.request;
00401 }
00402
00403 static str s_ip={"integrity-protected",19};
00414 int cscf_get_integrity_protected(struct sip_msg *msg,str realm)
00415 {
00416 struct hdr_field* h=0;
00417 int ret,i,j;
00418
00419 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00420 LOG(L_ERR,"ERR:"M_NAME":cscf_get_integrity_protected: Error parsing until header Authorization: \n");
00421 return 0;
00422 }
00423
00424 if (!msg->authorization){
00425 LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: Message does not contain Authorization header.\n");
00426 return 0;
00427 }
00428
00429 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00430 if (ret < 0) {
00431 LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: Error while looking for credentials.\n");
00432 return 0;
00433 } else
00434 if (ret > 0) {
00435 LOG(L_ERR, "ERR:"M_NAME":cscf_get_integrity_protected: No credentials for this realm found.\n");
00436 return 0;
00437 }
00438
00439 if (h) {
00440 for(i=0;i<h->body.len-s_ip.len;i++)
00441 if (strncasecmp(h->body.s+i,s_ip.s,s_ip.len)==0)
00442 for(j=i+s_ip.len;j<h->body.len;j++){
00443 if (h->body.s[j]=='y' || h->body.s[j]=='Y') return 1;
00444 if (h->body.s[j]==' ') return 0;
00445 }
00446 }
00447
00448 return 0;
00449 }
00450
00451
00461 int cscf_get_transaction(struct sip_msg *msg, unsigned int *hash,unsigned int *label)
00462 {
00463
00464 if (tmb.t_get_trans_ident(msg,hash,label)<0){
00465 LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: SIP message without transaction. OK - first request\n");
00466 if (tmb.t_newtran(msg)<0)
00467 LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00468 if (tmb.t_get_trans_ident(msg,hash,label)<0){
00469 LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: SIP message still without transaction\n");
00470 return -1;
00471 }else {
00472 LOG(L_DBG,"DBG:"M_NAME":cscf_get_transaction: New SIP message transaction %u %u\n",
00473 *hash,*label);
00474 return 1;
00475 }
00476 }else {
00477 LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Transaction %u %u exists."
00478 "Retransmission?\n",*hash,*label);
00479 return 0;
00480 }
00481 }
00482
00490 int cscf_reply_transactional(struct sip_msg *msg, int code, char *text)
00491 {
00492 unsigned int hash,label;
00493 if (tmb.t_get_trans_ident(msg,&hash,&label)<0){
00494
00495 if (tmb.t_newtran(msg)<0)
00496 LOG(L_INFO,"INF:"M_NAME":cscf_get_transaction: Failed creating SIP transaction\n");
00497 }
00498 return tmb.t_reply(msg,code,text);
00499 }
00500
00507 str cscf_get_auts(struct sip_msg *msg, str realm)
00508 {
00509 str name={"auts=\"",6};
00510 struct hdr_field* h=0;
00511 int i,ret;
00512 str auts={0,0};
00513
00514 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00515 LOG(L_ERR,"ERR:"M_NAME":cscf_get_auts: Error parsing until header Authorization: \n");
00516 return auts;
00517 }
00518
00519 if (!msg->authorization){
00520 LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: Message does not contain Authorization header.\n");
00521 return auts;
00522 }
00523
00524 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00525 if (ret < 0) {
00526 LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: Error while looking for credentials.\n");
00527 return auts;
00528 } else
00529 if (ret > 0) {
00530 LOG(L_ERR, "ERR:"M_NAME":cscf_get_auts: No credentials for this realm found.\n");
00531 return auts;
00532 }
00533
00534 if (h) {
00535 for(i=0;i<h->body.len-name.len;i++)
00536 if (strncasecmp(h->body.s+i,name.s,name.len)==0){
00537 auts.s = h->body.s+i+name.len;
00538 while(i+auts.len<h->body.len && auts.s[auts.len]!='\"')
00539 auts.len++;
00540 }
00541 }
00542
00543 return auts;
00544 }
00545
00552 str cscf_get_nonce(struct sip_msg *msg, str realm)
00553 {
00554 struct hdr_field* h=0;
00555 int ret;
00556 str nonce={0,0};
00557
00558 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00559 LOG(L_ERR,"ERR:"M_NAME":cscf_get_nonce: Error parsing until header Authorization: \n");
00560 return nonce;
00561 }
00562
00563 if (!msg->authorization){
00564 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Message does not contain Authorization header.\n");
00565 return nonce;
00566 }
00567
00568 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00569 if (ret < 0) {
00570 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Error while looking for credentials.\n");
00571 return nonce;
00572 } else
00573 if (ret > 0) {
00574 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: No credentials for this realm found.\n");
00575 return nonce;
00576 }
00577
00578 if (h&&h->parsed) {
00579 nonce = ((auth_body_t*)h->parsed)->digest.nonce;
00580 }
00581
00582 return nonce;
00583 }
00584
00591 str cscf_get_algorithm(struct sip_msg *msg, str realm)
00592 {
00593 struct hdr_field* h=0;
00594 int ret;
00595 str alg={0,0};
00596
00597 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00598 LOG(L_ERR,"ERR:"M_NAME":cscf_get_algorithm: Error parsing until header Authorization: \n");
00599 return alg;
00600 }
00601
00602 if (!msg->authorization){
00603 LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: Message does not contain Authorization header.\n");
00604 return alg;
00605 }
00606
00607 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00608 if (ret < 0) {
00609 LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: Error while looking for credentials.\n");
00610 return alg;
00611 } else
00612 if (ret > 0) {
00613 LOG(L_ERR, "ERR:"M_NAME":cscf_get_algorithm: No credentials for this realm found.\n");
00614 return alg;
00615 }
00616
00617 if (h&&h->parsed) {
00618 alg = ((auth_body_t*)h->parsed)->digest.alg.alg_str;
00619 }
00620 return alg;
00621 }
00622
00629 str cscf_get_digest_uri(struct sip_msg *msg, str realm)
00630 {
00631 struct hdr_field* h=0;
00632 int ret;
00633 str uri={0,0};
00634
00635 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00636 LOG(L_ERR,"ERR:"M_NAME":cscf_get_digest_uri: Error parsing until header Authorization: \n");
00637 return uri;
00638 }
00639
00640 if (!msg->authorization){
00641 LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: Message does not contain Authorization header.\n");
00642 return uri;
00643 }
00644
00645 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00646 if (ret < 0) {
00647 LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: Error while looking for credentials.\n");
00648 return uri;
00649 } else
00650 if (ret > 0) {
00651 LOG(L_ERR, "ERR:"M_NAME":cscf_get_digest_uri: No credentials for this realm found.\n");
00652 return uri;
00653 }
00654
00655 if (h&&h->parsed) {
00656 uri = ((auth_body_t*)h->parsed)->digest.uri;
00657 }
00658 return uri;
00659 }
00660
00669 int cscf_get_nonce_response(struct sip_msg *msg, str realm,str *nonce,str *response,
00670 enum qop_type *qop,str *qop_str,str *nc,str *cnonce,str *uri)
00671 {
00672 struct hdr_field* h=0;
00673 int ret;
00674
00675 if (parse_headers(msg,HDR_AUTHORIZATION_F,0)!=0) {
00676 LOG(L_ERR,"ERR:"M_NAME":cscf_get_nonce: Error parsing until header Authorization: \n");
00677 return 0;
00678 }
00679
00680 if (!msg->authorization){
00681 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Message does not contain Authorization header.\n");
00682 return 0;
00683 }
00684
00685 ret = find_credentials(msg, &realm, HDR_AUTHORIZATION_F, &h);
00686 if (ret < 0) {
00687 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: Error while looking for credentials.\n");
00688 return 0;
00689 } else
00690 if (ret > 0) {
00691 LOG(L_ERR, "ERR:"M_NAME":cscf_get_nonce: No credentials for this realm found.\n");
00692 return 0;
00693 }
00694
00695 if (h&&h->parsed) {
00696 if (nonce) *nonce = ((auth_body_t*)h->parsed)->digest.nonce;
00697 if (response) *response = ((auth_body_t*)h->parsed)->digest.response;
00698 if (qop) *qop = ((auth_body_t*)h->parsed)->digest.qop.qop_parsed;
00699 if (qop_str) *qop_str = ((auth_body_t*)h->parsed)->digest.qop.qop_str;
00700 if (nc) *nc = ((auth_body_t*)h->parsed)->digest.nc;
00701 if (cnonce) *cnonce = ((auth_body_t*)h->parsed)->digest.cnonce;
00702 if (uri) *uri = ((auth_body_t*)h->parsed)->digest.uri;
00703 }
00704
00705 return 1;
00706 }
00707
00708
00709 str ua_dummy={"Unknown UA",10};
00710 str ua_nomsg={"No Message",10};
00716 str cscf_get_user_agent(struct sip_msg *msg)
00717 {
00718 str ua;
00719 if (!msg) return ua_nomsg;
00720 ua.len = 0;
00721 if (parse_headers(msg, HDR_USERAGENT_F, 0) != -1 && msg->user_agent &&
00722 msg->user_agent->body.len > 0)
00723 {
00724 ua.len = msg->user_agent->body.len;
00725 ua.s = msg->user_agent->body.s;
00726 }
00727 if (ua.len == 0) ua=ua_dummy;
00728 return ua;
00729 }
00730
00736 contact_body_t *cscf_parse_contacts(struct sip_msg *msg)
00737 {
00738 struct hdr_field* ptr;
00739 if (!msg) return 0;
00740 if (parse_headers(msg, HDR_EOH_F, 0)<0){
00741 LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: Error parsing headers \n");
00742 return 0;
00743 }
00744 if (msg->contact) {
00745 ptr = msg->contact;
00746 while(ptr) {
00747 if (ptr->type == HDR_CONTACT_T) {
00748 if (ptr->parsed==0){
00749 if (parse_contact(ptr)<0){
00750 LOG(L_ERR,"ERR:"M_NAME":cscf_parse_contacts: error parsing contacts [%.*s]\n",
00751 ptr->body.len,ptr->body.s);
00752 }
00753 }
00754 }
00755 ptr = ptr->next;
00756 }
00757 }
00758 if (!msg->contact) return 0;
00759 return msg->contact->parsed;
00760 }
00761
00767 str cscf_get_path(struct sip_msg *msg)
00768 {
00769 str path={0,0};
00770 struct hdr_field *h;
00771 if (!msg) return path;
00772 if (parse_headers(msg, HDR_EOH_F, 0)<0){
00773 LOG(L_ERR,"ERR:"M_NAME":cscf_get_path: error parsing headers\n");
00774 return path;
00775 }
00776 h = msg->headers;
00777 while(h){
00778 if (h->name.len==4 &&
00779 strncasecmp(h->name.s,"Path",4)==0){
00780 path.len+=h->body.len+1;
00781 }
00782 h = h->next;
00783 }
00784 path.s = pkg_malloc(path.len);
00785 if (!path.s){
00786 LOG(L_ERR,"ERR:"M_NAME":cscf_get_path: error allocating %d bytes\n",
00787 path.len);
00788 path.len=0;
00789 return path;
00790 }
00791 h = msg->headers;
00792 path.len=0;
00793 while(h){
00794 if (h->name.len==4 &&
00795 strncasecmp(h->name.s,"Path",4)==0){
00796 if (path.len) path.s[path.len++]=',';
00797 memcpy(path.s+path.len,h->body.s,h->body.len);
00798 path.len+=h->body.len;
00799 }
00800 h = h->next;
00801 }
00802
00803 return path;
00804 }
00805
00811 str cscf_get_event(struct sip_msg *msg)
00812 {
00813 str e={0,0};
00814 if (!msg) return e;
00815 if (parse_headers(msg, HDR_EVENT_F, 0) != -1 && msg->event &&
00816 msg->event->body.len > 0)
00817 {
00818 e.len = msg->event->body.len;
00819 e.s = msg->event->body.s;
00820 }
00821 return e;
00822 }
00823
00824
00825 str s_asserted_identity={"P-Asserted-Identity",19};
00831 str cscf_get_asserted_identity(struct sip_msg *msg)
00832 {
00833 name_addr_t id;
00834 struct hdr_field *h;
00835 rr_t *r;
00836 memset(&id,0,sizeof(name_addr_t));
00837 if (!msg) return id.uri;
00838 if (parse_headers(msg, HDR_EOH_F, 0)<0) {
00839 return id.uri;
00840 }
00841 h = msg->headers;
00842 while(h)
00843 {
00844 if (h->name.len == s_asserted_identity.len &&
00845 strncasecmp(h->name.s,s_asserted_identity.s,s_asserted_identity.len)==0)
00846 {
00847 if (parse_rr(h)<0){
00848
00849 LOG(L_CRIT,"WARN:"M_NAME":cscf_get_asserted_identity: P-Asserted-Identity header must contain a Nameaddr!!! Fix the client!\n");
00850 id.name.s = h->body.s;
00851 id.name.len = 0;
00852 id.len = h->body.len;
00853 id.uri = h->body;
00854 while(id.uri.len && (id.uri.s[0]==' ' || id.uri.s[0]=='\t' || id.uri.s[0]=='<')){
00855 id.uri.s = id.uri.s+1;
00856 id.uri.len --;
00857 }
00858 while(id.uri.len && (id.uri.s[id.uri.len-1]==' ' || id.uri.s[id.uri.len-1]=='\t' || id.uri.s[id.uri.len-1]=='>')){
00859 id.uri.len--;
00860 }
00861 return id.uri;
00862 }
00863 r = (rr_t*) h->parsed;
00864 id = r->nameaddr;
00865 free_rr(&r);
00866 h->parsed=r;
00867
00868 return id.uri;
00869 }
00870 h = h->next;
00871 }
00872 return id.uri;
00873 }
00874
00880 str cscf_get_asserted_identity_domain(struct sip_msg *msg)
00881 {
00882 struct sip_uri puri;
00883 str uri = cscf_get_asserted_identity(msg);
00884 if (!uri.len) return uri;
00885
00886 if (parse_uri(uri.s,uri.len,&puri)<0){
00887 LOG(L_ERR,"ERR:"M_NAME":cscf_get_asserted_identity_domain: error parsing uri <%.*s>\n",
00888 uri.len,uri.s);
00889 uri.len=0;uri.s=0;
00890 return uri;
00891 }
00892 return puri.host;
00893 }
00894
00900 str cscf_get_contact(struct sip_msg *msg)
00901 {
00902 str id={0,0};
00903 struct hdr_field *h;
00904 struct contact_body *cb;
00905
00906 if (!msg) return id;
00907 if (parse_headers(msg, HDR_CONTACT_F, 0)<0) {
00908 LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Error parsing headers until Contact.\n");
00909 return id;
00910 }
00911
00912 h = msg->contact;
00913 if (!h) {
00914 LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Contact header not found.\n");
00915 return id;
00916 }
00917 if (h->parsed==0 &&
00918 parse_contact(h)<0){
00919 LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: Error parsing contacts.\n");
00920 return id;
00921 }
00922
00923 cb = (struct contact_body *)h->parsed;
00924 if (!cb || !cb->contacts){
00925 LOG(L_ERR,"ERR:"M_NAME":cscf_get_contact: No contacts in header.\n");
00926 return id;
00927 }
00928 id = cb->contacts->uri;
00929
00930 return id;
00931 }
00932
00933
00940 str cscf_get_first_route(struct sip_msg *msg,struct hdr_field **hr)
00941 {
00942 struct hdr_field *h;
00943 rr_t *r;
00944 str route={0,0};
00945 if (hr) *hr = 0;
00946 if (!msg) return route;
00947 if (parse_headers(msg, HDR_ROUTE_F, 0)<0){
00948 LOG(L_ERR,"ERR:"M_NAME":cscf_get_first_route: error parsing headers\n");
00949 return route;
00950 }
00951 h = msg->route;
00952 if (!h){
00953 LOG(L_DBG,"DBG:"M_NAME":cscf_get_first_route: Header Route not found\n");
00954 return route;
00955 }
00956 if (hr) *hr = h;
00957 if (parse_rr(h)<0){
00958 LOG(L_ERR,"ERR:"M_NAME":cscf_get_first_route: Error parsing as Route header\n");
00959 return route;
00960 }
00961 r = (rr_t*)h->parsed;
00962 route = r->nameaddr.uri;
00963
00964 return route;
00965 }
00966
00967 static str route_hdr_s={"Route: ",7};
00968 static str route_hdr_e={"\r\n",2};
00976 int cscf_remove_first_route(struct sip_msg *msg,str value)
00977 {
00978 struct hdr_field *h;
00979 str route={0,0},x;
00980 int i;
00981
00982 route = cscf_get_first_route(msg,&h);
00983 if (!h||!route.len) return 0;
00984
00985 if ((route.len == value.len || (route.len>value.len && route.s[value.len]==';')) &&
00986 strncasecmp(route.s,value.s,value.len)==0)
00987 {
00988 cscf_del_header(msg,h);
00989 route = h->body;
00990 i=0;
00991 while(i<route.len && route.s[i]!=',')
00992 i++;
00993 i++;
00994 if (i<route.len){
00995 route.s+=i;
00996 route.len-=i;
00997 x.s = pkg_malloc(route_hdr_s.len + route.len +route_hdr_e.len);
00998 if (!x.s){
00999 LOG(L_ERR, "ERR"M_NAME":cscf_remove_first_route: Error allocating %d bytes\n",
01000 route.len);
01001 x.len=0;
01002 }else{
01003 x.len = 0;
01004 STR_APPEND(x,route_hdr_s);
01005 STR_APPEND(x,route);
01006 STR_APPEND(x,route_hdr_e);
01007 if (!cscf_add_header_first(msg,&x,HDR_ROUTE_T))
01008 pkg_free(x.s);
01009 }
01010 }
01011 }
01012
01013 return 1;
01014 }
01015
01016
01017
01023 inline int cscf_is_myself(str uri)
01024 {
01025 int ret;
01026 struct sip_uri puri;
01027
01028 if (parse_uri(uri.s,uri.len,&puri)<0){
01029 LOG(L_ERR,"ERR:"M_NAME":cscf_is_myself: error parsing uri <%.*s>\n",
01030 uri.len,uri.s);
01031 return 0;
01032 }
01033
01034 ret = check_self(&(puri.host), puri.port_no ? puri.port_no : SIP_PORT, 0);
01035 if (ret < 0) return 0;
01036
01037 return ret;
01038 }
01039
01047 int cscf_remove_own_route(struct sip_msg *msg,struct hdr_field **h)
01048 {
01049 str route={0,0},x;
01050 int i;
01051
01052 route = cscf_get_first_route(msg,h);
01053 if (!h||!route.len) return 0;
01054
01055 LOG(L_DBG,"DBG:"M_NAME":cscf_remove_own_route: <%.*s>\n",
01056 route.len,route.s);
01057 if (cscf_is_myself(route))
01058 {
01059 cscf_del_header(msg,*h);
01060 route = (*h)->body;
01061 i=0;
01062 while(i<route.len && route.s[i]!=',')
01063 i++;
01064 i++;
01065 if (i<route.len){
01066 route.s+=i;
01067 route.len-=i;
01068 x.s = pkg_malloc(route_hdr_s.len + route.len +route_hdr_e.len);
01069 if (!x.s){
01070 LOG(L_ERR, "ERR"M_NAME":cscf_remove_own_route: Error allocating %d bytes\n",
01071 route.len);
01072 x.len=0;
01073 }else{
01074 x.len = 0;
01075 STR_APPEND(x,route_hdr_s);
01076 STR_APPEND(x,route);
01077 STR_APPEND(x,route_hdr_e);
01078 if (!cscf_add_header_first(msg,&x,HDR_ROUTE_T))
01079 pkg_free(x.s);
01080 }
01081 }
01082 }
01083
01084 return 1;
01085 }
01086
01087
01088 static str s_record_route={"Record-route",12};
01094 str cscf_get_record_routes(struct sip_msg *msg)
01095 {
01096 struct hdr_field *h;
01097 str route={0,0};
01098
01099 if (!msg) return route;
01100
01101 if (parse_headers(msg, HDR_EOH_F, 0)<0){
01102 LOG(L_ERR,"ERR:"M_NAME":cscf_get_record_routes: error parsing headers\n");
01103 return route;
01104 }
01105 h = msg->record_route;
01106 while (h){
01107 if (h->name.len == s_record_route.len &&
01108 strncasecmp(h->name.s,s_record_route.s,s_record_route.len)==0)
01109 {
01110 LOG(L_DBG,"DBG:"M_NAME":cscf_get_record_routes: RR %.*s\n",h->body.len,h->body.s);
01111 if (route.s){
01112 route.s = pkg_realloc(route.s,route.len+1+h->body.len);
01113 route.s[route.len++]=',';
01114 }else{
01115 route.s = pkg_malloc(h->body.len);
01116 }
01117 memcpy(route.s+route.len,h->body.s,h->body.len);
01118 route.len+=h->body.len;
01119 }
01120 h = h->next;
01121 }
01122 return route;
01123 }
01124
01131 struct hdr_field* cscf_get_next_record_route(struct sip_msg *msg,struct hdr_field *start)
01132 {
01133 struct hdr_field *h;
01134
01135 if (!msg) return 0;
01136
01137
01138 if (parse_headers(msg, HDR_EOH_F, 0)<0){
01139 LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_record_routes: error parsing headers\n");
01140 return 0;
01141 }
01142 if (start) h = start->next;
01143 else h = msg->record_route;
01144 while (h){
01145 if (h->type == HDR_RECORDROUTE_T)
01146 {
01147 LOG(L_DBG,"DBG:"M_NAME":cscf_get_next_record_routes: RR %.*s\n",h->body.len,h->body.s);
01148 if (!h->parsed){
01149 if (parse_rr(h)<0){
01150 LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_record_routes: Error parsing as Route header\n");
01151 return 0;
01152 }
01153 }
01154 return h;
01155 }
01156 h = h->next;
01157 }
01158 return 0;
01159 }
01160
01167 struct hdr_field* cscf_get_next_via_hdr(struct sip_msg *msg,struct hdr_field *start)
01168 {
01169 struct hdr_field *h;
01170
01171 if (!msg) return 0;
01172
01173 if (parse_headers(msg, HDR_EOH_F, 0)<0){
01174 LOG(L_ERR,"ERR:"M_NAME":cscf_get_next_via: error parsing headers\n");
01175 return 0;
01176 }
01177 if (start) h = start->next;
01178 else h = msg->headers;
01179 while (h){
01180 if (h->type == HDR_VIA_T)
01181 return h;
01182 h = h->next;
01183 }
01184 return 0;
01185 }
01186
01191 static int str_trim(str *s)
01192 {
01193 int i;
01194 for (i = 0;i < s->len; i++)
01195 {
01196 if (s->s[i] != '\r' && s->s[i] != '\t' && s->s[i] != ' ')
01197 {
01198 break;
01199 }
01200 }
01201 s->s = s->s + i;
01202 s->len -= i;
01203
01204 for (i = s->len;i >=0; i--)
01205 {
01206 if (s->s[i] == '\r' && s->s[i] == '\t' && s->s[i] == ' ')
01207 {
01208 s->len--;
01209 }
01210 else
01211 {
01212 break;
01213 }
01214 }
01215 return 1;
01216 }
01217
01229 str cscf_get_next_via_str(struct sip_msg *msg, struct hdr_field * h, int pos, struct hdr_field **h_out, int *pos_out)
01230 {
01231 char *viab;
01232 int i, viab_start;
01233 str via_str={0,0};
01234 if (!h_out || !pos_out)
01235 return via_str;
01236
01237 if (!h)
01238 {
01239 h = cscf_get_next_via_hdr(msg,0);
01240 pos = 0;
01241 }
01242
01243 viab = h->body.s;
01244 i = viab_start = pos;
01245
01246 while (i < h->body.len)
01247 {
01248 if (viab[i] == ',')
01249 {
01250 via_str.s = viab + viab_start;
01251 via_str.len = i - viab_start;
01252 str_trim(&via_str);
01253 viab_start = i+1;
01254 *h_out = h;
01255 *pos_out = viab_start;
01256 return via_str;
01257 }
01258 i++;
01259 }
01260 via_str.s = viab + viab_start;
01261 via_str.len = i - viab_start;
01262 str_trim(&via_str);
01263 *h_out = cscf_get_next_via_hdr(msg,h);
01264 *pos_out = 0;
01265 return via_str;
01266 }
01267
01274 int cscf_via_matching( struct via_body *req_via, struct via_body *rpl_via )
01275 {
01276 if ((!req_via->branch && rpl_via->branch) || (req_via->branch && !rpl_via->branch))
01277 {
01278 LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: branch param missing\n");
01279 return 0;;
01280 }
01281 if (req_via->branch && rpl_via->branch)
01282 {
01283 if (req_via->branch->value.len != rpl_via->branch->value.len ||
01284 strncasecmp(req_via->branch->value.s, rpl_via->branch->value.s,rpl_via->branch->value.len)!=0)
01285 {
01286 LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different branch param\n");
01287 return 0;
01288 }
01289 }
01290 if (req_via->host.len!=rpl_via->host.len||
01291 strncasecmp(req_via->host.s, rpl_via->host.s,rpl_via->host.len)!=0)
01292 {
01293 LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different host \n");
01294 return 0;
01295 }
01296 if (req_via->port!=rpl_via->port)
01297 {
01298 LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: different port \n");
01299 return 0;
01300 }
01301
01302 if (req_via->transport.len!=rpl_via->transport.len||
01303 strncasecmp(req_via->transport.s, rpl_via->transport.s,rpl_via->transport.len)!=0)
01304 {
01305 LOG(L_INFO,"DBG:"M_NAME":cscf_via_matching: transport host \n");
01306 return 0;
01307 }
01308
01309 return 1;
01310 }
01311
01312
01313
01314
01315
01316 static inline void free_via_param_list(struct via_param* vp)
01317 {
01318 struct via_param* foo;
01319 while(vp){
01320 foo=vp;
01321 vp=vp->next;
01322 pkg_free(foo);
01323 }
01324 }
01325
01326 static str via_hdr_term={"\r\n.",3};
01334 int cscf_str_via_matching(str *sreq_via, str *srpl_via)
01335 {
01336 struct via_body req_via, rpl_via;
01337 str hdr1={0,0}, hdr2={0,0};
01338 int result = 0;
01339
01340 memset(&req_via, 0, sizeof(struct via_body));
01341 memset(&rpl_via, 0, sizeof(struct via_body));
01342
01343 if (sreq_via->s[sreq_via->len+1] !='\r' || sreq_via->s[sreq_via->len+2] != '\n')
01344 {
01345 hdr1.len = sreq_via->len + via_hdr_term.len;
01346 hdr1.s = pkg_malloc(hdr1.len);
01347 if (!hdr1.s)
01348 {
01349 LOG(L_ERR, "ERR:"M_NAME":cscf_str_via_matching: cannot alloc bytes : %d", hdr1.len);
01350 return 0;
01351 }
01352 hdr1.len=0;
01353 STR_APPEND(hdr1, *sreq_via);
01354 STR_APPEND(hdr1, via_hdr_term);
01355 parse_via(hdr1.s,hdr1.s+hdr1.len,&req_via);
01356 }
01357 else
01358 parse_via(sreq_via->s,sreq_via->s+sreq_via->len, &req_via);
01359
01360
01361 if (srpl_via->s[srpl_via->len+1] !='\r' || srpl_via->s[srpl_via->len+2] != '\n')
01362 {
01363 hdr2.len = srpl_via->len + via_hdr_term.len;
01364 hdr2.s = pkg_malloc(hdr2.len);
01365 if (!hdr2.s)
01366 {
01367 LOG(L_ERR, "ERR:"M_NAME":cscf_str_via_matching: cannot alloc bytes : %d", hdr2.len);
01368 goto done;
01369 }
01370 hdr2.len=0;
01371 STR_APPEND(hdr2, *srpl_via);
01372 STR_APPEND(hdr2, via_hdr_term);
01373 parse_via(hdr2.s,hdr2.s+hdr2.len,&rpl_via);
01374 }
01375 else
01376 parse_via(srpl_via->s, srpl_via->s+srpl_via->len, &rpl_via);
01377
01378 result = cscf_via_matching(&req_via, &rpl_via);
01379
01380 done:
01381 if (hdr1.s) pkg_free(hdr1.s);
01382 if (hdr1.s) pkg_free(hdr2.s);
01383 if (req_via.param_lst) free_via_param_list(req_via.param_lst);
01384 if (rpl_via.param_lst) free_via_param_list(rpl_via.param_lst);
01385 return result;
01386 }
01387
01388
01389
01395 str cscf_get_realm_from_ruri(struct sip_msg *msg)
01396 {
01397 str realm={0,0};
01398 if (!msg || msg->first_line.type!=SIP_REQUEST){
01399 LOG(L_ERR,"ERR:"M_NAME":cscf_get_realm_from_ruri: This is not a request!!!\n");
01400 return realm;
01401 }
01402 if (!msg->parsed_orig_ruri_ok)
01403 if (parse_orig_ruri(msg) < 0)
01404 return realm;
01405
01406 realm = msg->parsed_orig_ruri.host;
01407 return realm;
01408 }
01409
01415 str cscf_get_identity_from_ruri(struct sip_msg *msg)
01416 {
01417 str aor={0,0};
01418 if (!msg || msg->first_line.type!=SIP_REQUEST){
01419 LOG(L_ERR,"ERR:"M_NAME":cscf_get_identity_from_ruri: This is not a request!!!\n");
01420 return aor;
01421 }
01422 aor.s = msg->first_line.u.request.uri.s;
01423 aor.len = 0;
01424 while(aor.s[aor.len]!=' '&&aor.s[aor.len]!='\t'&&
01425 aor.s[aor.len]!=';'&&aor.s[aor.len]!='&'&&
01426 aor.s[aor.len]!='\r'&&aor.s[aor.len]!='\n')
01427 aor.len++;
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 return aor;
01439 }
01440
01441
01448 str cscf_get_call_id(struct sip_msg *msg,struct hdr_field **hr)
01449 {
01450 struct hdr_field *h;
01451 str call_id={0,0};
01452 if (hr) *hr = 0;
01453 if (!msg) return call_id;
01454 if (parse_headers(msg, HDR_CALLID_F, 0)<0){
01455 LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: error parsing headers\n");
01456 return call_id;
01457 }
01458 h = msg->callid;
01459 if (!h){
01460 LOG(L_ERR,"ERR:"M_NAME":cscf_get_call_id: Header Call-ID not found\n");
01461 return call_id;
01462 }
01463 if (hr) *hr = h;
01464 call_id = h->body;
01465 return call_id;
01466 }
01467
01468
01475 int cscf_get_cseq(struct sip_msg *msg,struct hdr_field **hr)
01476 {
01477 struct hdr_field *h;
01478 struct cseq_body *cseq;
01479 int nr = 0,i;
01480
01481 if (hr) *hr = 0;
01482 if (!msg) return 0;
01483 if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
01484 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
01485 return 0;
01486 }
01487 h = msg->cseq;
01488 if (!h){
01489 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01490 return 0;
01491 }
01492 if (hr) *hr = h;
01493 if (!h->parsed){
01494 cseq = pkg_malloc(sizeof(struct cseq_body));
01495 if (!cseq){
01496 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01497 return 0;
01498 }
01499 parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
01500 h->parsed = cseq;
01501 }else
01502 cseq = (struct cseq_body*) h->parsed;
01503 for(i=0;i<cseq->number.len;i++)
01504 nr = (nr*10)+(cseq->number.s[i]-'0');
01505 return nr;
01506 }
01507
01514 str cscf_get_cseq_method(struct sip_msg *msg,struct hdr_field **hr)
01515 {
01516 struct hdr_field *h;
01517 struct cseq_body *cseq;
01518 str method = {0,0};
01519
01520 if (hr) *hr = 0;
01521 if (!msg) return method;
01522 if (parse_headers(msg, HDR_CSEQ_F, 0)<0){
01523 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: error parsing headers\n");
01524 return method;
01525 }
01526 h = msg->cseq;
01527 if (!h){
01528 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01529 return method;
01530 }
01531 if (hr) *hr = h;
01532 if (!h->parsed){
01533 cseq = pkg_malloc(sizeof(struct cseq_body));
01534 if (!cseq){
01535 LOG(L_ERR,"ERR:"M_NAME":cscf_get_cseq: Header CSeq not found\n");
01536 return method;
01537 }
01538 parse_cseq(h->body.s,h->body.s+h->body.len,cseq);
01539 h->parsed = cseq;
01540 }else
01541 cseq = (struct cseq_body*) h->parsed;
01542 return cseq->method;
01543 }
01544
01550 struct sip_msg* cscf_get_request_from_reply(struct sip_msg *reply)
01551 {
01552 struct cell *t;
01553 t = tmb.t_gett();
01554 if (!t || t==(void*) -1){
01555 LOG(L_ERR,"ERR:"M_NAME":cscf_get_request_from_reply: Reply without transaction\n");
01556 return 0;
01557 }
01558 if (t) return t->uas.request;
01559 else return 0;
01560 }
01561
01562
01563 static str s_called_party_id={"P-Called-Party-ID",17};
01570 str cscf_get_called_party_id(struct sip_msg *msg,struct hdr_field **hr)
01571 {
01572 str id={0,0};
01573 struct hdr_field *h;
01574 if (hr) *hr=0;
01575 if (!msg) return id;
01576 if (parse_headers(msg, HDR_EOH_F, 0)<0) {
01577 return id;
01578 }
01579 h = msg->headers;
01580 while(h)
01581 {
01582 if (h->name.len == s_called_party_id.len &&
01583 strncasecmp(h->name.s,s_called_party_id.s,s_called_party_id.len)==0)
01584 {
01585 id = h->body;
01586 while(id.len && (id.s[0]==' ' || id.s[0]=='\t' || id.s[0]=='<')){
01587 id.s = id.s+1;
01588 id.len --;
01589 }
01590 while(