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
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044
00045 #include "../../parser/msg_parser.h"
00046 #include "../../parser/parse_to.h"
00047 #include "../../parser/parse_via.h"
00048 #include "../../parser/parse_uri.h"
00049 #include "../../mem/mem.h"
00050 #include "../../dprint.h"
00051 #include "../../md5utils.h"
00052 #include "exec_hf.h"
00053
00054
00055 unsigned int setvars=1;
00056
00057
00058 static int insert_hf( struct hf_wrapper **list, struct hdr_field *hf )
00059 {
00060 struct hf_wrapper *w;
00061 struct hf_wrapper *i;
00062
00063 w=(struct hf_wrapper *)pkg_malloc(sizeof(struct hf_wrapper));
00064 if (!w) {
00065 LM_ERR("ran out of pkg mem\n");
00066 return 0;
00067 }
00068 memset(w, 0, sizeof(struct hf_wrapper));
00069 w->var_type=W_HF;w->u.hf=hf;
00070 w->prefix=HF_PREFIX; w->prefix_len=HF_PREFIX_LEN;
00071
00072
00073 for(i=*list; i; i=i->next_other) {
00074 if (i->var_type==W_HF && i->u.hf->type==hf->type) {
00075
00076 if (hf->type==HDR_OTHER_T && (hf->name.len!=i->u.hf->name.len
00077 || strncasecmp(i->u.hf->name.s, hf->name.s,
00078 hf->name.len)!=0))
00079 continue;
00080
00081 w->next_same=i->next_same;
00082 w->next_other=i->next_other;
00083 i->next_same=w;
00084 break;
00085 }
00086 }
00087
00088 if (i==0) {
00089 w->next_other=*list;
00090 *list=w;
00091 }
00092 return 1;
00093 }
00094
00095 static void release_hf_struct( struct hf_wrapper *list )
00096 {
00097 struct hf_wrapper *i, *j, *nexts, *nexto;
00098
00099 i=list;
00100 while(i) {
00101 nexto=i->next_other;
00102 j=i->next_same;
00103 pkg_free(i);
00104
00105 while(j) {
00106 nexts=j->next_same;
00107 pkg_free(j);
00108 j=nexts;
00109 }
00110 i=nexto;
00111 }
00112 }
00113
00114
00115
00116
00117 static int compacthdr_type2str(hdr_types_t type, char **hname, int *hlen )
00118 {
00119 switch(type) {
00120
00121
00122 case HDR_VIA_T :
00123 *hname=VAR_VIA;
00124 *hlen=VAR_VIA_LEN;
00125 break;
00126 case HDR_CONTENTTYPE_T :
00127 *hname=VAR_CTYPE;
00128 *hlen=VAR_CTYPE_LEN;
00129 break;
00130 case HDR_FROM_T :
00131 *hname=VAR_FROM;
00132 *hlen=VAR_FROM_LEN;
00133 break;
00134 case HDR_CALLID_T :
00135 *hname=VAR_CALLID;
00136 *hlen=VAR_CALLID_LEN;
00137 break;
00138 case HDR_SUPPORTED_T :
00139 *hname=VAR_SUPPORTED;
00140 *hlen=VAR_SUPPORTED_LEN;
00141 break;
00142 case HDR_CONTENTLENGTH_T :
00143 *hname=VAR_CLEN;
00144 *hlen=VAR_CLEN_LEN;
00145 break;
00146 case HDR_CONTACT_T :
00147 *hname=VAR_CONTACT;
00148 *hlen=VAR_CONTACT_LEN;
00149 break;
00150 case HDR_TO_T :
00151 *hname=VAR_TO;
00152 *hlen=VAR_TO_LEN;
00153 break;
00154 case HDR_EVENT_T :
00155 *hname=VAR_EVENT;
00156 *hlen=VAR_EVENT_LEN;
00157 break;
00158 default:
00159 return 0;
00160 }
00161 return 1;
00162 }
00163
00164
00165 static int canonize_headername(str *orig, char **hname, int *hlen )
00166 {
00167 char *c;
00168 int i;
00169
00170 *hlen=orig->len;
00171 *hname=pkg_malloc(*hlen);
00172 if (!*hname) {
00173 LM_ERR("no pkg mem for hname\n");
00174 return 0;
00175 }
00176 for (c=orig->s, i=0; i<*hlen; i++, c++) {
00177
00178 if (*c>='a' && *c<='z')
00179 *((*hname)+i)=*c-('a'-'A');
00180
00181 else if ((*c>='A' && *c<='Z')||(*c>='0' && *c<='9'))
00182 *((*hname)+i)=*c;
00183
00184 else if (strchr(UNRESERVED_MARK HNV_UNRESERVED, *c)
00185 || (*c==ESCAPE))
00186 *((*hname)+i)=HFN_SYMBOL;
00187 else {
00188 LM_ERR("print_var unexpected char '%c' in hfname %.*s\n",
00189 *c, *hlen, orig->s );
00190 *((*hname)+i)=HFN_SYMBOL;
00191 }
00192 }
00193 return 1;
00194 }
00195
00196
00197 static int print_av_var(struct hf_wrapper *w)
00198 {
00199 int env_len;
00200 char *env;
00201 char *c;
00202
00203 env_len=w->u.av.attr.len+1+w->u.av.val.len+1;
00204 env=pkg_malloc(env_len);
00205 if (!env) {
00206 LM_ERR("no pkg mem\n");
00207 return 0;
00208 }
00209 c=env;
00210 memcpy(c, w->u.av.attr.s, w->u.av.attr.len); c+=w->u.av.attr.len;
00211 *c=EV_ASSIGN;c++;
00212 memcpy(c, w->u.av.val.s, w->u.av.val.len);c+=w->u.av.val.len;
00213 *c=0;
00214 w->envvar=env;
00215 return 1;
00216 }
00217
00218
00219
00220 static int print_hf_var(struct hf_wrapper *w, int offset)
00221 {
00222 char *hname;
00223 int hlen;
00224 short canonical;
00225 char *envvar;
00226 int envvar_len;
00227 struct hf_wrapper *wi;
00228 char *c;
00229
00230
00231 hname=0;hlen=0;envvar=0;
00232
00233
00234
00235
00236 canonical=compacthdr_type2str(w->u.hf->type, &hname, &hlen);
00237
00238
00239 if (!canonical) {
00240 if (!canonize_headername(&w->u.hf->name, &hname, &hlen)) {
00241 LM_ERR("canonize_hn error\n");
00242 return 0;
00243 }
00244 }
00245
00246 envvar_len=w->u.hf->body.len;
00247 for(wi=w->next_same; wi; wi=wi->next_same) {
00248 envvar_len+=1 + wi->u.hf->body.len;
00249 }
00250 envvar=pkg_malloc(w->prefix_len+hlen+1+envvar_len+1);
00251 if (!envvar) {
00252 LM_ERR("no pkg mem\n");
00253 goto error00;
00254 }
00255 memcpy(envvar, w->prefix, w->prefix_len); c=envvar+w->prefix_len;
00256 memcpy(c, hname, hlen ); c+=hlen;
00257 *c=EV_ASSIGN;c++;
00258 memcpy(c, w->u.hf->body.s+offset, w->u.hf->body.len );
00259 c+=w->u.hf->body.len;
00260 for (wi=w->next_same; wi; wi=wi->next_same) {
00261 *c=HF_SEPARATOR;c++;
00262 memcpy(c, wi->u.hf->body.s+offset, wi->u.hf->body.len );
00263 c+=wi->u.hf->body.len;
00264 }
00265 *c=0;
00266 LM_DBG("%s\n", envvar );
00267
00268 w->envvar=envvar;
00269 if (!canonical) pkg_free(hname);
00270 return 1;
00271
00272 error00:
00273 if (!canonical) pkg_free(hname);
00274 return 0;
00275 }
00276
00277 static int print_var(struct hf_wrapper *w, int offset)
00278 {
00279 switch(w->var_type) {
00280 case W_HF:
00281 return print_hf_var(w, offset);
00282 case W_AV:
00283 return print_av_var(w);
00284 default:
00285 LM_CRIT("unknown type: %d\n", w->var_type );
00286 return 0;
00287 }
00288 }
00289
00290 static void release_vars(struct hf_wrapper *list)
00291 {
00292 while(list) {
00293 if (list->envvar) {
00294 pkg_free(list->envvar);
00295 list->envvar=0;
00296 }
00297 list=list->next_other;
00298 }
00299 }
00300
00301
00302 static int build_hf_struct(struct sip_msg *msg, struct hf_wrapper **list)
00303 {
00304 struct hdr_field *h;
00305
00306 *list=0;
00307
00308 for (h=msg->headers; h; h=h->next) {
00309 if (!insert_hf(list,h)) {
00310 LM_ERR("insert_hf failed\n");
00311 goto error00;
00312 }
00313 }
00314 return 1;
00315 error00:
00316 release_hf_struct(*list);
00317 *list=0;
00318 return 0;
00319
00320 }
00321
00322
00323 static int create_vars(struct hf_wrapper *list, int offset)
00324 {
00325 int var_cnt;
00326 struct hf_wrapper *w;
00327
00328
00329 var_cnt=0;
00330 for(w=list;w;w=w->next_other) {
00331 if (!print_var(w, offset)) {
00332 LM_ERR("create_vars failed\n");
00333 return 0;
00334 }
00335 var_cnt++;
00336 }
00337
00338 return var_cnt;
00339 }
00340
00341 environment_t *replace_env(struct hf_wrapper *list)
00342 {
00343 int var_cnt;
00344 char **cp;
00345 struct hf_wrapper *w;
00346 char **new_env;
00347 int i;
00348 environment_t *backup_env;
00349
00350 backup_env=(environment_t *)pkg_malloc(sizeof(environment_t));
00351 if (!backup_env) {
00352 LM_ERR("no pkg mem for backup env\n");
00353 return 0;
00354 }
00355
00356
00357 var_cnt=0;
00358 for (cp=environ; *cp; cp++) var_cnt++;
00359 backup_env->old_cnt=var_cnt;
00360
00361 for(w=list;w;w=w->next_other) var_cnt++;
00362 new_env=pkg_malloc((var_cnt+1)*sizeof(char *));
00363 if (!new_env) {
00364 LM_ERR("no pkg mem\n");
00365 return 0;
00366 }
00367
00368 i=0;
00369 for (cp=environ; *cp; cp++) {
00370 new_env[i]=*cp;
00371 i++;
00372 }
00373 for (w=list;w;w=w->next_other) {
00374 new_env[i]=w->envvar;
00375 i++;
00376 }
00377 new_env[i]=0;
00378
00379 backup_env->env=environ;
00380 environ=new_env;
00381
00382 return backup_env;
00383 }
00384
00385 void unset_env(environment_t *backup_env)
00386 {
00387 char **cur_env, **cur_env0;
00388 int i;
00389
00390
00391 cur_env0=cur_env=environ;
00392 environ=backup_env->env;
00393 i=0;
00394
00395 while(*cur_env) {
00396
00397 if (i>=backup_env->old_cnt) {
00398 pkg_free(*cur_env);
00399 }
00400 cur_env++;
00401 i++;
00402 }
00403 pkg_free(cur_env0);
00404 pkg_free(backup_env);
00405 }
00406
00407 static int append_var(char *name, char *value, int len, struct hf_wrapper **list)
00408 {
00409 struct hf_wrapper *w;
00410
00411 w=(struct hf_wrapper *)pkg_malloc(sizeof(struct hf_wrapper));
00412 if (!w) {
00413 LM_ERR("ran out of pkg mem\n");
00414 return 0;
00415 }
00416 memset(w, 0, sizeof(struct hf_wrapper));
00417 w->var_type=W_AV;
00418 w->u.av.attr.s=name;
00419 w->u.av.attr.len=strlen(name);
00420 w->u.av.val.s=value;
00421
00422 w->u.av.val.len= value==0?0:(len==0? strlen(value) : len);
00423 w->next_other=*list;
00424 *list=w;
00425 return 1;
00426 }
00427
00428 static int append_fixed_vars(struct sip_msg *msg, struct hf_wrapper **list)
00429 {
00430 static char tid[MD5_LEN];
00431 str *uri;
00432 struct sip_uri parsed_uri, oparsed_uri;
00433 char *val;
00434 int val_len;
00435
00436
00437 if (!append_var(EV_SRCIP, ip_addr2a(&msg->rcv.src_ip), 0, list)) {
00438 LM_ERR("append_var SRCIP failed \n");
00439 return 0;
00440 }
00441
00442 uri=msg->new_uri.s && msg->new_uri.len ?
00443 &msg->new_uri : &msg->first_line.u.request.uri;
00444 if (!append_var(EV_RURI, uri->s, uri->len, list )) {
00445 LM_ERR("append_var URI failed\n");
00446 return 0;
00447 }
00448
00449 if (parse_uri(uri->s, uri->len, &parsed_uri)<0) {
00450 LM_WARN("uri not parsed\n");
00451 } else {
00452 if (!append_var(EV_USER, parsed_uri.user.s,
00453 parsed_uri.user.len, list)) {
00454 LM_ERR("append_var USER failed\n");
00455 goto error;
00456 }
00457 }
00458
00459 if (!append_var(EV_ORURI, msg->first_line.u.request.uri.s,
00460 msg->first_line.u.request.uri.len, list)) {
00461 LM_ERR("append_var O-URI failed\n");
00462 goto error;
00463 }
00464
00465 if (parse_uri(msg->first_line.u.request.uri.s,
00466 msg->first_line.u.request.uri.len,
00467 &oparsed_uri)<0) {
00468 LM_WARN("orig URI not parsed\n");
00469 } else {
00470 if (!append_var(EV_OUSER, oparsed_uri.user.s,
00471 oparsed_uri.user.len, list)) {
00472 LM_ERR("ppend_var OUSER failed\n");
00473 goto error;
00474 }
00475 }
00476
00477 if (!char_msg_val(msg, tid)) {
00478 LM_WARN("no tid can be determined\n");
00479 val=0; val_len=0;
00480 } else {
00481 val=tid;val_len=MD5_LEN;
00482 }
00483 if (!append_var(EV_TID, val,val_len, list)) {
00484 LM_ERR("append_var TID failed\n");
00485 goto error;
00486 }
00487
00488
00489 if (!(msg->to && get_to(msg) )) {
00490 LM_ERR("no to-tag\n");
00491 val=0; val_len=0;
00492 } else {
00493 val=get_to(msg)->tag_value.s;
00494 val_len=get_to(msg)->tag_value.len;
00495 }
00496 if (!append_var(EV_DID, val, val_len, list)) {
00497 LM_ERR("append_var DID failed\n");
00498 goto error;
00499 }
00500 return 1;
00501 error:
00502 return 0;
00503 }
00504
00505 environment_t *set_env(struct sip_msg *msg)
00506 {
00507 struct hf_wrapper *hf_list;
00508 environment_t *backup_env;
00509
00510
00511 if (parse_headers(msg, HDR_EOH_F, 0)==-1) {
00512 LM_ERR("parsing failed\n");
00513 return 0;
00514 }
00515
00516 hf_list=0;
00517
00518
00519 if (!build_hf_struct(msg, &hf_list)) {
00520 LM_ERR("build_hf_struct failed\n");
00521 return 0;
00522 }
00523 if (!append_fixed_vars(msg, &hf_list)) {
00524 LM_ERR("append_fixed_vars failed\n");
00525 goto error01;
00526 }
00527
00528 if (!create_vars(hf_list, 0)) {
00529 LM_ERR("create_vars failed\n");
00530 goto error00;
00531 }
00532
00533 backup_env=replace_env(hf_list);
00534 if (!backup_env) {
00535 LM_ERR("replace_env failed\n");
00536 goto error00;
00537 }
00538
00539 release_hf_struct(hf_list);
00540 return backup_env;
00541
00542 error00:
00543 release_vars(hf_list);
00544 error01:
00545 release_hf_struct(hf_list);
00546 return 0;
00547 }
00548