exec_hf.c 14 KB

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