rpid.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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-04-28 rpid contributed by Juha Heinanen added (janakj)
  25. * 2005-05-31 general avp specification added for rpid (bogdan)
  26. */
  27. /*!
  28. * \file
  29. * \brief Remote-Party-ID related functions
  30. * \ingroup auth
  31. * - Module: \ref auth
  32. */
  33. #include <string.h>
  34. #include <strings.h>
  35. #include "../../str.h"
  36. #include "../../data_lump.h"
  37. #include "../../dprint.h"
  38. #include "../../mem/mem.h"
  39. #include "../../parser/parse_nameaddr.h"
  40. #include "../../parser/parse_uri.h"
  41. #include "../../parser/parser_f.h"
  42. #include "../../ut.h"
  43. #include "../../pvar.h"
  44. #include "rpid.h"
  45. #define RPID_HF_NAME "Remote-Party-ID: "
  46. #define RPID_HF_NAME_LEN (sizeof(RPID_HF_NAME) - 1)
  47. extern str rpid_prefix; /*!< Remote-Party-ID prefix */
  48. extern str rpid_suffix; /*!< Remote-Party-ID suffix */
  49. /* rpid AVP specs */
  50. static unsigned short rpid_avp_type;
  51. static int_str rpid_avp_name;
  52. /*!
  53. * \brief Parse and set the RPID AVP specs
  54. * \param rpid_avp_param RPID AVP parameter
  55. * \return 0 on success, -1 on failure
  56. */
  57. int init_rpid_avp(char *rpid_avp_param)
  58. {
  59. pv_spec_t avp_spec;
  60. str stmp;
  61. if (rpid_avp_param && *rpid_avp_param) {
  62. stmp.s = rpid_avp_param; stmp.len = strlen(stmp.s);
  63. if (pv_parse_spec(&stmp, &avp_spec)==0
  64. || avp_spec.type!=PVT_AVP) {
  65. LM_ERR("malformed or non AVP %s AVP definition\n", rpid_avp_param);
  66. return -1;
  67. }
  68. if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp_name,
  69. &rpid_avp_type)!=0)
  70. {
  71. LM_ERR("[%s]- invalid AVP definition\n", rpid_avp_param);
  72. return -1;
  73. }
  74. } else {
  75. rpid_avp_name.n = 0;
  76. rpid_avp_type = 0;
  77. }
  78. return 0;
  79. }
  80. /*!
  81. * \brief Gets the RPID avp specs
  82. * \param rpid_avp_p AVP name
  83. * \param rpid_avp_type_p AVP type
  84. */
  85. void get_rpid_avp( int_str *rpid_avp_p, int *rpid_avp_type_p )
  86. {
  87. *rpid_avp_p = rpid_avp_name;
  88. *rpid_avp_type_p = rpid_avp_type;
  89. }
  90. /*!
  91. * \brief Check if user is a E164 number
  92. * \param _user user
  93. * \note Copy of is_e164 from enum module
  94. * \return 1 if its a E164 number, -1 if not
  95. */
  96. static inline int is_e164(str* _user)
  97. {
  98. int i;
  99. char c;
  100. if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
  101. for (i = 1; i < _user->len; i++) {
  102. c = (_user->s)[i];
  103. if ((c < '0') || (c > '9')) return -1;
  104. }
  105. return 1;
  106. } else {
  107. return -1;
  108. }
  109. }
  110. /*!
  111. * \brief Append RPID helper function
  112. * \param _m SIP message
  113. * \param _s appended string
  114. * \note Copy of append_hf_helper from textops
  115. * \return 0 on success, negative on failure
  116. */
  117. static inline int append_rpid_helper(struct sip_msg* _m, str *_s)
  118. {
  119. struct lump* anchor;
  120. if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
  121. LM_ERR("failed to parse message\n");
  122. return -1;
  123. }
  124. anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
  125. if (!anchor) {
  126. LM_ERR("can't get anchor\n");
  127. return -2;
  128. }
  129. if (!insert_new_lump_before(anchor, _s->s, _s->len, 0)) {
  130. LM_ERR("can't insert lump\n");
  131. return -3;
  132. }
  133. return 0;
  134. }
  135. /*!
  136. * \brief Append RPID header field to the message
  137. * \param _m SIP message
  138. * \param _s1 unused
  139. * \param _s2 unused
  140. * \return 1 on success, -1 on failure
  141. */
  142. int append_rpid_hf(struct sip_msg* _m, char* _s1, char* _s2)
  143. {
  144. struct usr_avp *avp;
  145. str rpid_hf, rpid;
  146. char *at;
  147. int_str val;
  148. if (rpid_avp_name.n==0) {
  149. LM_ERR("rpid avp not defined\n");
  150. return -1;
  151. }
  152. if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
  153. LM_DBG("no rpid AVP\n");
  154. return -1;
  155. }
  156. if ( !(avp->flags&AVP_VAL_STR) || !val.s.s || !val.s.len) {
  157. LM_DBG("empty or non-string rpid, nothing to append\n");
  158. return -1;
  159. }
  160. rpid = val.s;
  161. rpid_hf.len = RPID_HF_NAME_LEN + rpid_prefix.len + rpid.len
  162. + rpid_suffix.len + CRLF_LEN;
  163. rpid_hf.s = pkg_malloc(rpid_hf.len);
  164. if (!rpid_hf.s) {
  165. LM_ERR("no memory left\n");
  166. return -1;
  167. }
  168. at = rpid_hf.s;
  169. memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
  170. at += RPID_HF_NAME_LEN;
  171. memcpy(at, rpid_prefix.s, rpid_prefix.len);
  172. at += rpid_prefix.len;
  173. memcpy(at, rpid.s, rpid.len);
  174. at += rpid.len;
  175. memcpy(at, rpid_suffix.s, rpid_suffix.len);
  176. at += rpid_suffix.len;
  177. memcpy(at, CRLF, CRLF_LEN);
  178. if (append_rpid_helper(_m, &rpid_hf) < 0) {
  179. pkg_free(rpid_hf.s);
  180. return -1;
  181. }
  182. return 1;
  183. }
  184. /*!
  185. * \brief Append RPID header field to the message with parameters
  186. * \param _m SIP message
  187. * \param _prefix prefix
  188. * \param _suffix suffix
  189. * \return 1 on success, -1 on failure
  190. */
  191. int append_rpid_hf_p(struct sip_msg* _m, char* _prefix, char* _suffix)
  192. {
  193. struct usr_avp *avp;
  194. str rpid_hf, rpid;
  195. char* at;
  196. str* p, *s;
  197. int_str val;
  198. if (rpid_avp_name.n==0) {
  199. LM_ERR("rpid avp not defined\n");
  200. return -1;
  201. }
  202. if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
  203. LM_DBG("no rpid AVP\n");
  204. return -1;
  205. }
  206. if ( !(avp->flags&AVP_VAL_STR) || !val.s.s || !val.s.len) {
  207. LM_DBG("empty or non-string rpid, nothing to append\n");
  208. return -1;
  209. }
  210. rpid = val.s;
  211. p = (str*)_prefix;
  212. s = (str*)_suffix;
  213. rpid_hf.len = RPID_HF_NAME_LEN + p->len + rpid.len + s->len + CRLF_LEN;
  214. rpid_hf.s = pkg_malloc(rpid_hf.len);
  215. if (!rpid_hf.s) {
  216. LM_ERR("no pkg memory left\n");
  217. return -1;
  218. }
  219. at = rpid_hf.s;
  220. memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
  221. at += RPID_HF_NAME_LEN;
  222. memcpy(at, p->s, p->len);
  223. at += p->len;
  224. memcpy(at, rpid.s, rpid.len);
  225. at += rpid.len;
  226. memcpy(at, s->s, s->len);
  227. at += s->len;
  228. memcpy(at, CRLF, CRLF_LEN);
  229. if (append_rpid_helper(_m, &rpid_hf) < 0) {
  230. pkg_free(rpid_hf.s);
  231. return -1;
  232. }
  233. return 1;
  234. }
  235. /*!
  236. * \brief Check if URI in RPID AVP contains an E164 user part
  237. * \param _m SIP message
  238. * \param _s1 unused
  239. * \param _s2 unused
  240. * \return 1 if the URI contains an E164 user part, -1 if not
  241. */
  242. int is_rpid_user_e164(struct sip_msg* _m, char* _s1, char* _s2)
  243. {
  244. struct usr_avp *avp;
  245. name_addr_t parsed;
  246. str tmp, rpid;
  247. struct sip_uri uri;
  248. int_str val;
  249. if (rpid_avp_name.n==0) {
  250. LM_ERR("rpid avp not defined\n");
  251. return -1;
  252. }
  253. if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
  254. LM_DBG("no rpid AVP\n");
  255. goto err;
  256. }
  257. if ( !(avp->flags&AVP_VAL_STR) || !val.s.s || !val.s.len) {
  258. LM_DBG("empty or non-string rpid, nothing to append\n");
  259. return -1;
  260. }
  261. rpid = val.s;
  262. if (find_not_quoted(&rpid, '<')) {
  263. if (parse_nameaddr(&rpid, &parsed) < 0) {
  264. LM_ERR("failed to parse RPID\n");
  265. goto err;
  266. }
  267. tmp = parsed.uri;
  268. } else {
  269. tmp = rpid;
  270. }
  271. if (parse_uri(tmp.s, tmp.len, &uri) < 0) {
  272. LM_ERR("failed to parse RPID URI\n");
  273. goto err;
  274. }
  275. return is_e164(&uri.user);
  276. err:
  277. return -1;
  278. }