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
00036
00037 #include <ctype.h>
00038
00039 #include "../../parser/parse_from.h"
00040 #include "../../mem/mem.h"
00041 #include "../../data_lump.h"
00042 #include "../tm/h_table.h"
00043 #include "../tm/tm_load.h"
00044 #include "../rr/api.h"
00045
00046 #include "from.h"
00047
00048 extern str rr_param;
00049 extern str uac_passwd;
00050 extern int from_restore_mode;
00051 extern struct tm_binds uac_tmb;
00052 extern struct rr_binds uac_rrb;
00053
00054 static char enc_table64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00055 "abcdefghijklmnopqrstuvwxyz0123456789+/";
00056
00057 static int dec_table64[256];
00058
00059 static void restore_from_reply(struct cell* t, int type, struct tmcb_params *p);
00060 static void restore_to_reply(struct cell* t, int type, struct tmcb_params *p);
00061
00062 #define text3B64_len(_l) ( ( ((_l)+2)/3 ) << 2 )
00063
00064
00065 static int msg_id = 0;
00066
00067 void init_from_replacer(void)
00068 {
00069 int i;
00070
00071 for( i=0 ; i<256 ; i++)
00072 dec_table64[i] = -1;
00073 for ( i=0 ; i<64; i++)
00074 dec_table64[(unsigned char)enc_table64[i]] = i;
00075 }
00076
00077
00078 static inline int encode_from( str *src, str *dst )
00079 {
00080 static char buf[text3B64_len(MAX_URI_SIZE)];
00081 int idx;
00082 int left;
00083 int block;
00084 int i,r;
00085 char *p;
00086
00087 dst->len = text3B64_len( src->len );
00088 dst->s = buf;
00089 if (dst->len>text3B64_len(MAX_URI_SIZE))
00090 {
00091 LM_ERR("uri too long\n");
00092 return -1;
00093 }
00094
00095 for ( idx=0, p=buf ; idx<src->len ; idx+=3)
00096 {
00097 left = src->len - idx -1 ;
00098 left = (left>1? 2 : left);
00099
00100
00101 block = 0;
00102 for ( i=0,r= 16 ; i<=left ; i++,r-=8 )
00103 {
00104 block += ((unsigned char)src->s[idx+i]) << r;
00105 }
00106
00107
00108 *(p++) = enc_table64[(block >> 18) & 0x3f];
00109 *(p++) = enc_table64[(block >> 12) & 0x3f];
00110 *(p++) = left > 0 ? enc_table64[(block >> 6) & 0x3f] : '-';
00111 *(p++) = left > 1 ? enc_table64[block & 0x3f] : '-';
00112 }
00113
00114 return 0;
00115 }
00116
00117
00118 static inline int decode_from( str *src , str *dst)
00119 {
00120 static char buf[MAX_URI_SIZE];
00121 int block;
00122 int n;
00123 int idx;
00124 int end;
00125 int i,j;
00126 char c;
00127
00128
00129 for( n=0,i=src->len-1; src->s[i]=='-'; i--)
00130 n++;
00131
00132 dst->len = ((src->len * 6) >> 3) - n;
00133 dst->s = buf;
00134 if (dst->len>MAX_URI_SIZE)
00135 {
00136 LM_ERR("uri too long\n");
00137 return -1;
00138 }
00139
00140 end = src->len - n;
00141 for ( i=0,idx=0 ; i<end ; idx+=3 )
00142 {
00143
00144 block = 0;
00145 for ( j=0; j<4 && i<end ; j++)
00146 {
00147 c = dec_table64[(unsigned char)src->s[i++]];
00148 if ( c<0 )
00149 {
00150 LM_ERR("invalid base64 string\"%.*s\"\n",src->len,src->s);
00151 return -1;
00152 }
00153 block += c << (18 - 6*j);
00154 }
00155
00156
00157 for ( j=0,n=16 ; j<3 && idx+j< dst->len; j++,n-=8 )
00158 buf[idx+j] = (char) ((block >> n) & 0xff);
00159 }
00160
00161 return 0;
00162 }
00163
00164
00165 static inline struct lump* get_fdisplay_anchor(struct sip_msg *msg,
00166 struct to_body *from, str *dsp)
00167 {
00168 struct lump* l;
00169 char *p1;
00170 char *p2;
00171
00172
00173 p1 = msg->from->name.s + msg->from->name.len;
00174 for( p2=from->uri.s-1 ; p2>=p1 && *p2!='<' ; p2--);
00175
00176 if (*p2=='<') {
00177
00178 l = anchor_lump( msg, p2 - msg->buf, 0, 0);
00179 if (l==0) {
00180 LM_ERR("unable to build lump anchor\n");
00181 return 0;
00182 }
00183 dsp->s[dsp->len++] = ' ';
00184 return l;
00185 }
00186
00187
00188 l = anchor_lump( msg, (from->uri.s+from->uri.len) - msg->buf, 0, 0);
00189 if (l==0) {
00190 LM_ERR("unable to build lump anchor\n");
00191 return 0;
00192 }
00193 p1 = (char*)pkg_malloc(1);
00194 if (p1==0) {
00195 LM_ERR("no more pkg mem \n");
00196 return 0;
00197 }
00198 *p1 = '>';
00199 if (insert_new_lump_after( l, p1, 1, 0)==0) {
00200 LM_ERR("insert lump failed\n");
00201 pkg_free(p1);
00202 return 0;
00203 }
00204
00205 l = anchor_lump( msg, from->uri.s - msg->buf, 0, 0);
00206 if (l==0) {
00207 LM_ERR("unable to build lump anchor\n");
00208 return 0;
00209 }
00210 dsp->s[dsp->len++] = ' ';
00211 dsp->s[dsp->len++] = '<';
00212 return l;
00213 }
00214
00215
00216
00217
00218
00219 int replace_from( struct sip_msg *msg, str *from_dsp, str *from_uri)
00220 {
00221 static char buf_s[MAX_URI_SIZE];
00222 struct to_body *from;
00223 struct lump* l;
00224 str replace;
00225 char *p;
00226 str param;
00227 str buf;
00228 int i;
00229
00230
00231
00232 if (from_restore_mode==FROM_AUTO_RESTORE && from_uri && from_uri->len) {
00233 if ( msg->to==0 && (parse_headers(msg,HDR_TO_F,0)!=0 || msg->to==0) ) {
00234 LM_ERR("failed to parse TO hdr\n");
00235 goto error;
00236 }
00237 if (get_to(msg)->tag_value.len!=0) {
00238 LM_ERR("decline FROM replacing in sequential request in auto mode (has TO tag)\n");
00239 goto error;
00240 }
00241 }
00242
00243
00244 if (parse_from_header(msg)<0 )
00245 {
00246 LM_ERR("failed to find/parse FROM hdr\n");
00247 goto error;
00248 }
00249 from = (struct to_body*)msg->from->parsed;
00250
00251 if (from->param_lst==0)
00252 {
00253 LM_ERR("broken FROM hdr; no tag param\n");
00254 goto error;
00255 }
00256
00257
00258 if (from_dsp)
00259 {
00260
00261 l = 0;
00262
00263 if ( from->display.len)
00264 {
00265 LM_DBG("removing display [%.*s]\n",from->display.len,from->display.s);
00266
00267 l = del_lump( msg, from->display.s-msg->buf, from->display.len, 0);
00268 if (l==0)
00269 {
00270 LM_ERR("display del lump failed\n");
00271 goto error;
00272 }
00273 }
00274
00275 if (from_dsp->len)
00276 {
00277
00278 buf.s = pkg_malloc( from_dsp->len + 2 );
00279 if (buf.s==0)
00280 {
00281 LM_ERR("no more pkg mem\n");
00282 goto error;
00283 }
00284 memcpy( buf.s, from_dsp->s, from_dsp->len);
00285 buf.len = from_dsp->len;
00286 if (l==0 && (l=get_fdisplay_anchor(msg,from,&buf))==0)
00287 {
00288 LM_ERR("failed to insert anchor\n");
00289 goto error;
00290 }
00291 if (insert_new_lump_after( l, buf.s, buf.len, 0)==0)
00292 {
00293 LM_ERR("insert new display lump failed\n");
00294 pkg_free(buf.s);
00295 goto error;
00296 }
00297 }
00298 }
00299
00300
00301 if (from_uri==0 || from_uri->len==0 )
00302
00303 return 0;
00304
00305 LM_DBG("uri to replace [%.*s]\n",from->uri.len, from->uri.s);
00306 LM_DBG("replacement uri is [%.*s]\n",from_uri->len, from_uri->s);
00307
00308
00309 if ((l=del_lump( msg, from->uri.s-msg->buf, from->uri.len, 0))==0)
00310 {
00311 LM_ERR("del lump failed\n");
00312 goto error;
00313 }
00314 p = pkg_malloc( from_uri->len);
00315 if (p==0)
00316 {
00317 LM_ERR("no more pkg mem\n");
00318 goto error;
00319 }
00320 memcpy( p, from_uri->s, from_uri->len);
00321 if (insert_new_lump_after( l, p, from_uri->len, 0)==0)
00322 {
00323 LM_ERR("insert new lump failed\n");
00324 pkg_free(p);
00325 goto error;
00326 }
00327
00328 if (from_restore_mode==FROM_NO_RESTORE)
00329 return 0;
00330
00331
00332 buf.s = buf_s;
00333 if ( from->uri.len>from_uri->len ) {
00334 if (from->uri.len>MAX_URI_SIZE) {
00335 LM_ERR("old from uri to long\n");
00336 goto error;
00337 }
00338 memcpy( buf.s, from->uri.s, from->uri.len);
00339 for( i=0 ; i<from_uri->len ; i++ )
00340 buf.s[i] ^=from_uri->s[i];
00341 buf.len = from->uri.len;
00342 } else {
00343 if (from_uri->len>MAX_URI_SIZE) {
00344 LM_ERR("new from uri to long\n");
00345 goto error;
00346 }
00347 memcpy( buf.s, from_uri->s, from_uri->len);
00348 for( i=0 ; i<from->uri.len ; i++ )
00349 buf.s[i] ^=from->uri.s[i];
00350 buf.len = from_uri->len;
00351 }
00352
00353
00354 if (uac_passwd.len)
00355 for( i=0 ; i<buf.len ; i++)
00356 buf.s[i] ^= uac_passwd.s[i%uac_passwd.len];
00357
00358
00359 if (encode_from( &buf , &replace)<0 )
00360 {
00361 LM_ERR("failed to encode uris\n");
00362 goto error;
00363 }
00364 LM_DBG("encode is=<%.*s> len=%d\n",replace.len,replace.s,replace.len);
00365
00366
00367 param.len = 1+rr_param.len+1+replace.len;
00368 param.s = (char*)pkg_malloc(param.len);
00369 if (param.s==0)
00370 {
00371 LM_ERR("no more pkg mem\n");
00372 goto error;
00373 }
00374 p = param.s;
00375 *(p++) = ';';
00376 memcpy( p, rr_param.s, rr_param.len);
00377 p += rr_param.len;
00378 *(p++) = '=';
00379 memcpy( p, replace.s, replace.len);
00380 p += replace.len;
00381
00382 if (uac_rrb.add_rr_param( msg, ¶m)!=0)
00383 {
00384 LM_ERR("add_RR_param failed\n");
00385 goto error1;
00386 }
00387 msg->msg_flags |= FL_USE_UAC_FROM;
00388
00389
00390 if (uac_tmb.register_tmcb(msg,0,TMCB_RESPONSE_IN,restore_from_reply,0,0)!=1)
00391 {
00392 LM_ERR("failed to install TM callback\n");
00393 goto error1;
00394 }
00395
00396 pkg_free(param.s);
00397 return 0;
00398 error1:
00399 pkg_free(param.s);
00400 error:
00401 return -1;
00402 }
00403
00404
00405
00406
00407
00408
00409 int restore_from( struct sip_msg *msg, int *is_from )
00410 {
00411 struct lump* l;
00412 str param_val;
00413 str old_uri;
00414 str new_uri;
00415 char *p;
00416 int i;
00417 int flag;
00418
00419
00420
00421
00422 LM_DBG("getting '%.*s' Route param\n",
00423 rr_param.len,rr_param.s);
00424
00425 if (uac_rrb.get_route_param( msg, &rr_param, ¶m_val)!=0) {
00426 LM_DBG("route param '%.*s' not found\n",
00427 rr_param.len,rr_param.s);
00428 goto failed;
00429 }
00430 LM_DBG("route param is '%.*s' (len=%d)\n",
00431 param_val.len,param_val.s,param_val.len);
00432
00433
00434 if (decode_from( ¶m_val, &new_uri)<0 ) {
00435 LM_ERR("failed to decode uri\n");
00436 goto failed;
00437 }
00438
00439
00440 if (uac_passwd.len)
00441 for( i=0 ; i<new_uri.len ; i++)
00442 new_uri.s[i] ^= uac_passwd.s[i%uac_passwd.len];
00443
00444
00445 if (uac_rrb.is_direction( msg, RR_FLOW_UPSTREAM)==0) {
00446
00447 if ( msg->to==0 && (parse_headers(msg,HDR_TO_F,0)!=0 || msg->to==0) ) {
00448 LM_ERR("failed to parse TO hdr\n");
00449 goto failed;
00450 }
00451 old_uri = ((struct to_body*)msg->to->parsed)->uri;
00452 flag = FL_USE_UAC_TO;
00453 if (is_from) *is_from = 0;
00454 } else {
00455
00456 if ( parse_from_header(msg)<0 ) {
00457 LM_ERR("failed to find/parse FROM hdr\n");
00458 goto failed;
00459 }
00460 old_uri = ((struct to_body*)msg->from->parsed)->uri;
00461 flag = FL_USE_UAC_FROM;
00462 if (is_from) *is_from = 1;
00463 }
00464
00465
00466 if ( new_uri.len<old_uri.len ) {
00467 LM_ERR("new URI shorter than old URI\n");
00468 goto failed;
00469 }
00470 for( i=0 ; i<old_uri.len ; i++ )
00471 new_uri.s[i] ^= old_uri.s[i];
00472 if (new_uri.len==old_uri.len) {
00473 for( ; new_uri.len && (new_uri.s[new_uri.len-1]==0) ; new_uri.len-- );
00474 if (new_uri.len==0) {
00475 LM_ERR("new URI got 0 len\n");
00476 goto failed;
00477 }
00478 }
00479
00480 LM_DBG("decoded uris are: new=[%.*s] old=[%.*s]\n",
00481 new_uri.len, new_uri.s, old_uri.len, old_uri.s);
00482
00483
00484 p = pkg_malloc( new_uri.len);
00485 if (p==0) {
00486 LM_ERR("no more pkg mem\n");
00487 goto failed;
00488 }
00489 memcpy( p, new_uri.s, new_uri.len);
00490 new_uri.s = p;
00491
00492
00493 l = del_lump( msg, old_uri.s-msg->buf, old_uri.len, 0);
00494 if (l==0) {
00495 LM_ERR("del lump failed\n");
00496 goto failed1;
00497 }
00498
00499 if (insert_new_lump_after( l, new_uri.s, new_uri.len, 0)==0) {
00500 LM_ERR("insert new lump failed\n");
00501 goto failed1;
00502 }
00503
00504 msg->msg_flags |= flag;
00505
00506 return 0;
00507 failed1:
00508 pkg_free(new_uri.s);
00509 failed:
00510 return -1;
00511 }
00512
00513
00514
00515
00516
00517 void rr_checker(struct sip_msg *msg, str *r_param, void *cb_param)
00518 {
00519 int is_from;
00520
00521 is_from = 0;
00522
00523 if ( restore_from( msg, &is_from)==0 ) {
00524
00525
00526
00527 if ( uac_tmb.register_tmcb( msg, 0, TMCB_RESPONSE_IN,
00528 is_from?restore_from_reply:restore_to_reply, 0, 0)!=1 ) {
00529 LM_ERR("failed to install TM callback\n");
00530 return;
00531 }
00532 }
00533 }
00534
00535
00536
00537
00538
00539 void restore_from_reply(struct cell* t, int type, struct tmcb_params *p)
00540 {
00541 struct lump* l;
00542 struct sip_msg *req;
00543 struct sip_msg *rpl;
00544 str new_val;
00545
00546 if ( !t || !t->uas.request || !p->rpl )
00547 return;
00548
00549 req = t->uas.request;
00550 rpl = p->rpl;
00551
00552
00553 if (parse_from_header( p->rpl )<0 ) {
00554 LM_ERR("failed to find/parse FROM hdr\n");
00555 return;
00556 }
00557
00558 LM_DBG("rpl->id = %d, code %d (current id %d)\n", rpl->id, p->code, msg_id);
00559 if (msg_id == rpl->id) {
00560 LM_DBG("No change, already done!\n");
00561 return;
00562 }
00563 msg_id = rpl->id;
00564
00565
00566 new_val.s = pkg_malloc( req->from->len );
00567 if (p==0) {
00568 LM_ERR("no more pkg mem\n");
00569 return;
00570 }
00571 memcpy( new_val.s, req->from->name.s, req->from->len);
00572 new_val.len = req->from->len;
00573
00574
00575 LM_DBG("removing <%.*s>\n",
00576 rpl->from->len,rpl->from->name.s);
00577 l = del_lump( rpl, rpl->from->name.s-rpl->buf, rpl->from->len, 0);
00578 if (l==0) {
00579 LM_ERR("del lump failed\n");
00580 return;
00581 }
00582
00583 LM_DBG("inserting <%.*s>\n",
00584 new_val.len,new_val.s);
00585 if (insert_new_lump_after( l, new_val.s, new_val.len, 0)==0) {
00586 LM_ERR("insert new lump failed\n");
00587 return;
00588 }
00589 }
00590
00591
00592
00593
00594 void restore_to_reply(struct cell* t, int type, struct tmcb_params *p)
00595 {
00596 struct lump* l;
00597 struct sip_msg *req;
00598 struct sip_msg *rpl;
00599 str new_val;
00600
00601 if ( !t || !t->uas.request || !p->rpl )
00602 return;
00603
00604 req = t->uas.request;
00605 rpl = p->rpl;
00606
00607
00608 if ( rpl->to==0 && (parse_headers(rpl,HDR_TO_F,0)!=0 || rpl->to==0) ) {
00609 LM_ERR("failed to parse TO hdr\n");
00610 return;
00611 }
00612
00613
00614 new_val.s = pkg_malloc( req->to->len );
00615 if (p==0) {
00616 LM_ERR("no more pkg mem\n");
00617 return;
00618 }
00619 memcpy( new_val.s, req->to->name.s, req->to->len);
00620 new_val.len = req->to->len;
00621
00622 LM_DBG("removing <%.*s>\n",
00623 rpl->to->len,rpl->to->name.s);
00624 l = del_lump( rpl, rpl->to->name.s-rpl->buf, rpl->to->len, 0);
00625 if (l==0) {
00626 LM_ERR("del lump failed\n");
00627 return;
00628 }
00629
00630 LM_DBG("inserting <%.*s>\n",
00631 new_val.len, new_val.s);
00632 if (insert_new_lump_after( l, new_val.s, new_val.len, 0)==0) {
00633 LM_ERR("insert new lump failed\n");
00634 return;
00635 }
00636 }
00637