exec_hf.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * history
  23. * -------
  24. * 2003-02-28 scratchpad compatibility abandoned
  25. * 2003-01-29 scratchpad removed
  26. * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
  27. * 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
  28. */
  29. /* functions for creating environment variables out of a request's
  30. * header; known compact header field names are translated to
  31. * canonical form; multiple header field occurrences are merged
  32. * into a single variable
  33. *
  34. * known limitations:
  35. * - compact header field names unknown to parser will not be translated to
  36. * canonical form. Thus, environment variables may have either name and
  37. * users have to check for both of them.
  38. * - symbols in header field names will be translated to underscore
  39. *
  40. */
  41. #include <stdlib.h>
  42. #include "../../parser/msg_parser.h"
  43. #include "../../parser/parse_to.h"
  44. #include "../../parser/parse_via.h"
  45. #include "../../parser/parse_uri.h"
  46. #include "../../mem/mem.h"
  47. #include "../../dprint.h"
  48. #include "../../md5utils.h"
  49. #include "../../char_msg_val.h"
  50. #include "exec_hf.h"
  51. extern int exec_bash_safety;
  52. /* should be environment variables set by header fields ? */
  53. unsigned int setvars=1;
  54. /* insert a new header field into the structure; */
  55. static int insert_hf( struct hf_wrapper **list, struct hdr_field *hf )
  56. {
  57. struct hf_wrapper *w; /* new wrapper */
  58. struct hf_wrapper *i;
  59. w=(struct hf_wrapper *)pkg_malloc(sizeof(struct hf_wrapper));
  60. if (!w) {
  61. LM_ERR("ran out of pkg mem\n");
  62. return 0;
  63. }
  64. memset(w, 0, sizeof(struct hf_wrapper));
  65. w->var_type=W_HF;w->u.hf=hf;
  66. w->prefix=HF_PREFIX; w->prefix_len=HF_PREFIX_LEN;
  67. /* is there another hf of the same type?... */
  68. for(i=*list; i; i=i->next_other) {
  69. if (i->var_type==W_HF && i->u.hf->type==hf->type) {
  70. /* if it is OTHER, check name too */
  71. if (hf->type==HDR_OTHER_T && (hf->name.len!=i->u.hf->name.len
  72. || strncasecmp(i->u.hf->name.s, hf->name.s,
  73. hf->name.len)!=0))
  74. continue;
  75. /* yes, we found a hf of same type */
  76. w->next_same=i->next_same;
  77. w->next_other=i->next_other;
  78. i->next_same=w;
  79. break;
  80. }
  81. }
  82. /* ... no previous HF of the same type found */
  83. if (i==0) {
  84. w->next_other=*list;
  85. *list=w;
  86. }
  87. return 1;
  88. }
  89. static void release_hf_struct( struct hf_wrapper *list )
  90. {
  91. struct hf_wrapper *i, *j, *nexts, *nexto;
  92. i=list;
  93. while(i) {
  94. nexto=i->next_other;
  95. j=i->next_same;
  96. pkg_free(i);
  97. /* release list of same type hf */
  98. while(j) {
  99. nexts=j->next_same;
  100. pkg_free(j);
  101. j=nexts;
  102. }
  103. i=nexto;
  104. }
  105. }
  106. /* if that is some of well-known header fields which have compact
  107. * form, return canonical form ... returns 1 and sets params;
  108. * 0 is returned otherwise */
  109. static int compacthdr_type2str(hdr_types_t type, char **hname, int *hlen )
  110. {
  111. switch(type) {
  112. /* HDR_CONTENT_ENCODING: 'e' -- unsupported by parser */
  113. /* HDR_SUBJECT: 's' -- unsupported by parser */
  114. case HDR_VIA_T /* v */ :
  115. *hname=VAR_VIA;
  116. *hlen=VAR_VIA_LEN;
  117. break;
  118. case HDR_CONTENTTYPE_T /* c */ :
  119. *hname=VAR_CTYPE;
  120. *hlen=VAR_CTYPE_LEN;
  121. break;
  122. case HDR_FROM_T /* f */:
  123. *hname=VAR_FROM;
  124. *hlen=VAR_FROM_LEN;
  125. break;
  126. case HDR_CALLID_T /* i */:
  127. *hname=VAR_CALLID;
  128. *hlen=VAR_CALLID_LEN;
  129. break;
  130. case HDR_SUPPORTED_T /* k */:
  131. *hname=VAR_SUPPORTED;
  132. *hlen=VAR_SUPPORTED_LEN;
  133. break;
  134. case HDR_CONTENTLENGTH_T /* l */:
  135. *hname=VAR_CLEN;
  136. *hlen=VAR_CLEN_LEN;
  137. break;
  138. case HDR_CONTACT_T /* m */:
  139. *hname=VAR_CONTACT;
  140. *hlen=VAR_CONTACT_LEN;
  141. break;
  142. case HDR_TO_T /* t */:
  143. *hname=VAR_TO;
  144. *hlen=VAR_TO_LEN;
  145. break;
  146. case HDR_EVENT_T /* o */:
  147. *hname=VAR_EVENT;
  148. *hlen=VAR_EVENT_LEN;
  149. break;
  150. default:
  151. return 0;
  152. }
  153. return 1;
  154. }
  155. static int canonize_headername(str *orig, char **hname, int *hlen )
  156. {
  157. char *c;
  158. int i;
  159. *hlen=orig->len;
  160. *hname=pkg_malloc(*hlen);
  161. if (!*hname) {
  162. LM_ERR("no pkg mem for hname\n");
  163. return 0;
  164. }
  165. for (c=orig->s, i=0; i<*hlen; i++, c++) {
  166. /* lowercase to uppercase */
  167. if (*c>='a' && *c<='z')
  168. *((*hname)+i)=*c-('a'-'A');
  169. /* uppercase and numbers stay "as is" */
  170. else if ((*c>='A' && *c<='Z')||(*c>='0' && *c<='9'))
  171. *((*hname)+i)=*c;
  172. /* legal symbols will be translated to underscore */
  173. else if (strchr(UNRESERVED_MARK HNV_UNRESERVED, *c)
  174. || (*c==ESCAPE))
  175. *((*hname)+i)=HFN_SYMBOL;
  176. else {
  177. LM_ERR("print_var unexpected char '%c' in hfname %.*s\n",
  178. *c, *hlen, orig->s );
  179. *((*hname)+i)=HFN_SYMBOL;
  180. }
  181. }
  182. return 1;
  183. }
  184. static int print_av_var(struct hf_wrapper *w)
  185. {
  186. int env_len;
  187. char *env;
  188. char *c;
  189. env_len=w->u.av.attr.len+1/*assignment*/+w->u.av.val.len+1/*ZT*/;
  190. env=pkg_malloc(env_len);
  191. if (!env) {
  192. LM_ERR("no pkg mem\n");
  193. return 0;
  194. }
  195. c=env;
  196. memcpy(c, w->u.av.attr.s, w->u.av.attr.len); c+=w->u.av.attr.len;
  197. *c=EV_ASSIGN;c++;
  198. memcpy(c, w->u.av.val.s, w->u.av.val.len);c+=w->u.av.val.len;
  199. *c=0; /* zero termination */
  200. w->envvar=env;
  201. return 1;
  202. }
  203. /* creates a malloc-ed string with environment variable; returns 1 on success,
  204. * 0 on failure */
  205. static int print_hf_var(struct hf_wrapper *w, int offset)
  206. {
  207. char *hname;
  208. int hlen;
  209. short canonical;
  210. char *envvar;
  211. int envvar_len;
  212. struct hf_wrapper *wi;
  213. char *c;
  214. /* make -Wall happy */
  215. hname=0;hlen=0;envvar=0;
  216. /* Make sure header names with possible compact forms
  217. * will be printed canonically
  218. */
  219. canonical=compacthdr_type2str(w->u.hf->type, &hname, &hlen);
  220. /* header field has not been made canonical using a table;
  221. * do it now by uppercasing header-field name */
  222. if (!canonical) {
  223. if (!canonize_headername(&w->u.hf->name, &hname, &hlen)) {
  224. LM_ERR("canonize_hn error\n");
  225. return 0;
  226. }
  227. }
  228. /* now we have a header name, let us generate the var */
  229. envvar_len=w->u.hf->body.len;
  230. for(wi=w->next_same; wi; wi=wi->next_same) { /* other values, separated */
  231. envvar_len+=1 /* separator */ + wi->u.hf->body.len;
  232. }
  233. envvar=pkg_malloc(w->prefix_len+hlen+1/*assignment*/+envvar_len+1/*ZT*/);
  234. if (!envvar) {
  235. LM_ERR("no pkg mem\n");
  236. goto error00;
  237. }
  238. memcpy(envvar, w->prefix, w->prefix_len); c=envvar+w->prefix_len;
  239. memcpy(c, hname, hlen ); c+=hlen;
  240. *c=EV_ASSIGN;c++;
  241. if (exec_bash_safety && w->u.hf->body.len>=4
  242. && !strncmp(w->u.hf->body.s, "() {", 4)) {
  243. memcpy(c, w->u.hf->body.s+offset+2, w->u.hf->body.len-2 );
  244. c+=(w->u.hf->body.len-2);
  245. } else {
  246. memcpy(c, w->u.hf->body.s+offset, w->u.hf->body.len );
  247. c+=w->u.hf->body.len;
  248. }
  249. for(wi=w->next_same; wi; wi=wi->next_same) {
  250. *c=HF_SEPARATOR;c++;
  251. if (exec_bash_safety && wi->u.hf->body.len>=4
  252. && !strncmp(wi->u.hf->body.s, "() {", 4)) {
  253. memcpy(c, wi->u.hf->body.s+offset+2, wi->u.hf->body.len-2 );
  254. c+=(wi->u.hf->body.len-2);
  255. } else {
  256. memcpy(c, wi->u.hf->body.s+offset, wi->u.hf->body.len );
  257. c+=wi->u.hf->body.len;
  258. }
  259. }
  260. *c=0; /* zero termination */
  261. LM_DBG("%s\n", envvar );
  262. w->envvar=envvar;
  263. if (!canonical) pkg_free(hname);
  264. return 1;
  265. error00:
  266. if (!canonical) pkg_free(hname);
  267. return 0;
  268. }
  269. static int print_var(struct hf_wrapper *w, int offset)
  270. {
  271. switch(w->var_type) {
  272. case W_HF:
  273. return print_hf_var(w, offset);
  274. case W_AV:
  275. return print_av_var(w);
  276. default:
  277. LM_CRIT("unknown type: %d\n", w->var_type );
  278. return 0;
  279. }
  280. }
  281. static void release_vars(struct hf_wrapper *list)
  282. {
  283. while(list) {
  284. if (list->envvar) {
  285. pkg_free(list->envvar);
  286. list->envvar=0;
  287. }
  288. list=list->next_other;
  289. }
  290. }
  291. /* create ordered HF structure in pkg memory */
  292. static int build_hf_struct(struct sip_msg *msg, struct hf_wrapper **list)
  293. {
  294. struct hdr_field *h;
  295. *list=0;
  296. /* create ordered header-field structure */
  297. for (h=msg->headers; h; h=h->next) {
  298. if (!insert_hf(list,h)) {
  299. LM_ERR("insert_hf failed\n");
  300. goto error00;
  301. }
  302. }
  303. return 1;
  304. error00:
  305. release_hf_struct(*list);
  306. *list=0;
  307. return 0;
  308. }
  309. /* create env vars in malloc memory */
  310. static int create_vars(struct hf_wrapper *list, int offset)
  311. {
  312. int var_cnt;
  313. struct hf_wrapper *w;
  314. /* create variables now */
  315. var_cnt=0;
  316. for(w=list;w;w=w->next_other) {
  317. if (!print_var(w, offset)) {
  318. LM_ERR("create_vars failed\n");
  319. return 0;
  320. }
  321. var_cnt++;
  322. }
  323. return var_cnt;
  324. }
  325. environment_t *replace_env(struct hf_wrapper *list)
  326. {
  327. int var_cnt;
  328. char **cp;
  329. struct hf_wrapper *w;
  330. char **new_env;
  331. int i;
  332. environment_t *backup_env;
  333. backup_env=(environment_t *)pkg_malloc(sizeof(environment_t));
  334. if (!backup_env) {
  335. LM_ERR("no pkg mem for backup env\n");
  336. return 0;
  337. }
  338. /* count length of current env list */
  339. var_cnt=0;
  340. for (cp=environ; *cp; cp++) var_cnt++;
  341. backup_env->old_cnt=var_cnt;
  342. /* count length of our extensions */
  343. for(w=list;w;w=w->next_other) var_cnt++;
  344. new_env=pkg_malloc((var_cnt+1)*sizeof(char *));
  345. if (!new_env) {
  346. LM_ERR("no pkg mem\n");
  347. pkg_free(backup_env);
  348. return 0;
  349. }
  350. /* put all var pointers into new environment */
  351. i=0;
  352. for (cp=environ; *cp; cp++) { /* replicate old env */
  353. new_env[i]=*cp;
  354. i++;
  355. }
  356. for (w=list;w;w=w->next_other) { /* append new env */
  357. new_env[i]=w->envvar;
  358. i++;
  359. }
  360. new_env[i]=0; /* zero termination */
  361. /* install new environment */
  362. backup_env->env=environ;
  363. environ=new_env;
  364. /* return previous environment */
  365. return backup_env;
  366. }
  367. void unset_env(environment_t *backup_env)
  368. {
  369. char **cur_env, **cur_env0;
  370. int i;
  371. /* switch-over to backup environment */
  372. cur_env0=cur_env=environ;
  373. environ=backup_env->env;
  374. i=0;
  375. /* release environment */
  376. while(*cur_env) {
  377. /* leave previously existing vars alone */
  378. if (i>=backup_env->old_cnt) {
  379. pkg_free(*cur_env);
  380. }
  381. cur_env++;
  382. i++;
  383. }
  384. pkg_free(cur_env0);
  385. pkg_free(backup_env);
  386. }
  387. static int append_var(char *name, char *value, int len, struct hf_wrapper **list)
  388. {
  389. struct hf_wrapper *w;
  390. w=(struct hf_wrapper *)pkg_malloc(sizeof(struct hf_wrapper));
  391. if (!w) {
  392. LM_ERR("ran out of pkg mem\n");
  393. return 0;
  394. }
  395. memset(w, 0, sizeof(struct hf_wrapper));
  396. w->var_type=W_AV;
  397. w->u.av.attr.s=name;
  398. w->u.av.attr.len=strlen(name);
  399. w->u.av.val.s=value;
  400. /* NULL strings considered empty, if len unknown, calculate it now */
  401. w->u.av.val.len= value==0?0:(len==0? strlen(value) : len);
  402. w->next_other=*list;
  403. *list=w;
  404. return 1;
  405. }
  406. static int append_fixed_vars(struct sip_msg *msg, struct hf_wrapper **list)
  407. {
  408. static char tid[MD5_LEN];
  409. str *uri;
  410. struct sip_uri parsed_uri, oparsed_uri;
  411. char *val;
  412. int val_len;
  413. /* source ip */
  414. if (!append_var(EV_SRCIP, ip_addr2a(&msg->rcv.src_ip), 0, list)) {
  415. LM_ERR("append_var SRCIP failed \n");
  416. return 0;
  417. }
  418. /* request URI */
  419. uri=msg->new_uri.s && msg->new_uri.len ?
  420. &msg->new_uri : &msg->first_line.u.request.uri;
  421. if (!append_var(EV_RURI, uri->s, uri->len, list )) {
  422. LM_ERR("append_var URI failed\n");
  423. return 0;
  424. }
  425. /* userpart of request URI */
  426. if (parse_uri(uri->s, uri->len, &parsed_uri)<0) {
  427. LM_WARN("uri not parsed\n");
  428. } else {
  429. if (!append_var(EV_USER, parsed_uri.user.s,
  430. parsed_uri.user.len, list)) {
  431. LM_ERR("append_var USER failed\n");
  432. goto error;
  433. }
  434. }
  435. /* original URI */
  436. if (!append_var(EV_ORURI, msg->first_line.u.request.uri.s,
  437. msg->first_line.u.request.uri.len, list)) {
  438. LM_ERR("append_var O-URI failed\n");
  439. goto error;
  440. }
  441. /* userpart of request URI */
  442. if (parse_uri(msg->first_line.u.request.uri.s,
  443. msg->first_line.u.request.uri.len,
  444. &oparsed_uri)<0) {
  445. LM_WARN("orig URI not parsed\n");
  446. } else {
  447. if (!append_var(EV_OUSER, oparsed_uri.user.s,
  448. oparsed_uri.user.len, list)) {
  449. LM_ERR("ppend_var OUSER failed\n");
  450. goto error;
  451. }
  452. }
  453. /* tid, transaction id == via/branch */
  454. if (!char_msg_val(msg, tid)) {
  455. LM_WARN("no tid can be determined\n");
  456. val=0; val_len=0;
  457. } else {
  458. val=tid;val_len=MD5_LEN;
  459. }
  460. if (!append_var(EV_TID, val,val_len, list)) {
  461. LM_ERR("append_var TID failed\n");
  462. goto error;
  463. }
  464. /* did, dialogue id == To-tag */
  465. if (!(msg->to && get_to(msg) )) {
  466. LM_ERR("no to-tag\n");
  467. val=0; val_len=0;
  468. } else {
  469. val=get_to(msg)->tag_value.s;
  470. val_len=get_to(msg)->tag_value.len;
  471. }
  472. if (!append_var(EV_DID, val, val_len, list)) {
  473. LM_ERR("append_var DID failed\n");
  474. goto error;
  475. }
  476. return 1;
  477. error:
  478. return 0;
  479. }
  480. environment_t *set_env(struct sip_msg *msg)
  481. {
  482. struct hf_wrapper *hf_list;
  483. environment_t *backup_env;
  484. /* parse all so that we can pass all header fields to script */
  485. if (parse_headers(msg, HDR_EOH_F, 0)==-1) {
  486. LM_ERR("parsing failed\n");
  487. return 0;
  488. }
  489. hf_list=0;
  490. /* create a temporary structure with ordered header fields
  491. * and create environment variables out of it */
  492. if (!build_hf_struct(msg, &hf_list)) {
  493. LM_ERR("build_hf_struct failed\n");
  494. return 0;
  495. }
  496. if (!append_fixed_vars(msg, &hf_list)) {
  497. LM_ERR("append_fixed_vars failed\n");
  498. goto error01;
  499. }
  500. /* create now the strings for environment variables */
  501. if (!create_vars(hf_list, 0)) {
  502. LM_ERR("create_vars failed\n");
  503. goto error00;
  504. }
  505. /* install the variables in current environment */
  506. backup_env=replace_env(hf_list);
  507. if (!backup_env) {
  508. LM_ERR("replace_env failed\n");
  509. goto error00;
  510. }
  511. /* release the ordered HF structure -- we only need the vars now */
  512. release_hf_struct(hf_list);
  513. return backup_env;
  514. error00:
  515. release_vars(hf_list); /* release variables */
  516. error01:
  517. release_hf_struct(hf_list); /* release temporary ordered HF struct */
  518. return 0;
  519. }