util.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * $Id$
  3. *
  4. * XMPP Module
  5. * This file is part of Kamailio, a free SIP server.
  6. *
  7. * Copyright (C) 2006 Voice Sistem S.R.L.
  8. *
  9. * Kamailio is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * Kamailio is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. *
  23. * Author: Andreea Spirea
  24. *
  25. */
  26. /*! \file
  27. * \brief Kamailio XMPP module - utilities
  28. * \ingroup xmpp
  29. */
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include "xmpp.h"
  34. #include "../../parser/parse_uri.h"
  35. #include "../../parser/parse_param.h"
  36. extern param_t *_xmpp_gwmap_list;
  37. /*! \brief decode sip:user*domain1\@domain2 -> user\@domain1
  38. * or based on gwmap sip:user\@sipdomain -> user\@xmppdomain
  39. * \note In many kinds of gateway scenarios, the % sign is a common character used
  40. * See the MSN XMPP transports for an example.
  41. */
  42. char *decode_uri_sip_xmpp(char *uri)
  43. {
  44. sip_uri_t puri;
  45. static char buf[512];
  46. char *p;
  47. param_t *it = NULL;
  48. if (!uri)
  49. return NULL;
  50. if (parse_uri(uri, strlen(uri), &puri) < 0) {
  51. LM_ERR("failed to parse URI\n");
  52. return NULL;
  53. }
  54. if(_xmpp_gwmap_list==0)
  55. {
  56. strncpy(buf, puri.user.s, sizeof(buf));
  57. buf[puri.user.len] = 0;
  58. /* replace domain separator */
  59. if ((p = strchr(buf, domain_separator)))
  60. *p = '@';
  61. } else {
  62. for(it=_xmpp_gwmap_list; it; it=it->next)
  63. {
  64. if(it->name.len==puri.host.len
  65. && strncasecmp(it->name.s, puri.host.s, it->name.len)==0)
  66. {
  67. break;
  68. }
  69. }
  70. if(it && it->body.len>0)
  71. {
  72. snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
  73. it->body.len, it->body.s);
  74. } else {
  75. snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
  76. puri.host.len, puri.host.s);
  77. }
  78. }
  79. return buf;
  80. }
  81. /*! \brief encode sip:user\@domain -> user*domain\@xmpp_domain
  82. * or based on gwmap sip:user\@sipdomain -> user\@xmppdomain
  83. */
  84. char *encode_uri_sip_xmpp(char *uri)
  85. {
  86. sip_uri_t puri;
  87. static char buf[512];
  88. param_t *it = NULL;
  89. if (!uri)
  90. return NULL;
  91. if (parse_uri(uri, strlen(uri), &puri) < 0) {
  92. LM_ERR("failed to parse URI\n");
  93. return NULL;
  94. }
  95. if(_xmpp_gwmap_list==0)
  96. {
  97. snprintf(buf, sizeof(buf), "%.*s%c%.*s@%s",
  98. puri.user.len, puri.user.s,
  99. domain_separator,
  100. puri.host.len, puri.host.s,
  101. xmpp_domain);
  102. } else {
  103. for(it=_xmpp_gwmap_list; it; it=it->next)
  104. {
  105. if(it->name.len==puri.host.len
  106. && strncasecmp(it->name.s, puri.host.s, it->name.len)==0)
  107. {
  108. break;
  109. }
  110. }
  111. if(it && it->body.len>0)
  112. {
  113. snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
  114. it->body.len, it->body.s);
  115. } else {
  116. snprintf(buf, 512, "%.*s@%.*s", puri.user.len, puri.user.s,
  117. puri.host.len, puri.host.s);
  118. }
  119. }
  120. return buf;
  121. }
  122. /*! \brief decode user*domain1\@domain2 -> sip:user\@domain1
  123. * or based on gwmap sip:user\@xmppdomain -> user\@sipdomain
  124. */
  125. char *decode_uri_xmpp_sip(char *jid)
  126. {
  127. static char buf[512];
  128. char *p;
  129. char tbuf[512];
  130. sip_uri_t puri;
  131. str sd;
  132. param_t *it = NULL;
  133. if (!jid)
  134. return NULL;
  135. if(_xmpp_gwmap_list==0)
  136. {
  137. snprintf(buf, sizeof(buf), "sip:%s", jid);
  138. /* strip off resource */
  139. if ((p = strchr(buf, '/')))
  140. *p = 0;
  141. /* strip off domain */
  142. if ((p = strchr(buf, '@')))
  143. *p = 0;
  144. /* replace domain separator */
  145. if ((p = strchr(buf, domain_separator)))
  146. *p = '@';
  147. } else {
  148. snprintf(tbuf, sizeof(tbuf), "sip:%s", jid);
  149. /* strip off resource */
  150. if ((p = strchr(tbuf, '/')))
  151. *p = 0;
  152. if (parse_uri(tbuf, strlen(tbuf), &puri) < 0) {
  153. LM_ERR("failed to parse URI\n");
  154. return NULL;
  155. }
  156. for(it=_xmpp_gwmap_list; it; it=it->next)
  157. {
  158. if(it->body.len>0)
  159. {
  160. sd = it->body;
  161. } else {
  162. sd = it->name;
  163. }
  164. if(sd.len==puri.host.len
  165. && strncasecmp(sd.s, puri.host.s, sd.len)==0)
  166. {
  167. break;
  168. }
  169. }
  170. if(it)
  171. {
  172. snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
  173. it->name.len, it->name.s);
  174. } else {
  175. snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
  176. puri.host.len, puri.host.s);
  177. }
  178. }
  179. return buf;
  180. }
  181. /*! \brief encode user\@domain -> sip:user*domain\@gateway_domain
  182. * or based on gwmap sip:user\@xmppdomain -> user\@sipdomain
  183. */
  184. char *encode_uri_xmpp_sip(char *jid)
  185. {
  186. static char buf[512];
  187. char *p;
  188. char tbuf[512];
  189. sip_uri_t puri;
  190. str sd;
  191. param_t *it = NULL;
  192. if (!jid)
  193. return NULL;
  194. if(_xmpp_gwmap_list==0)
  195. {
  196. /* TODO: maybe not modify jid? */
  197. if ((p = strchr(jid, '/')))
  198. *p = 0;
  199. if ((p = strchr(jid, '@')))
  200. *p = domain_separator;
  201. snprintf(buf, sizeof(buf), "sip:%s@%s", jid, gateway_domain);
  202. } else {
  203. snprintf(tbuf, sizeof(tbuf), "sip:%s", jid);
  204. /* strip off resource */
  205. if ((p = strchr(tbuf, '/')))
  206. *p = 0;
  207. if (parse_uri(tbuf, strlen(tbuf), &puri) < 0) {
  208. LM_ERR("failed to parse URI\n");
  209. return NULL;
  210. }
  211. for(it=_xmpp_gwmap_list; it; it=it->next)
  212. {
  213. if(it->body.len>0)
  214. {
  215. sd = it->body;
  216. } else {
  217. sd = it->name;
  218. }
  219. if(sd.len==puri.host.len
  220. && strncasecmp(sd.s, puri.host.s, sd.len)==0)
  221. {
  222. break;
  223. }
  224. }
  225. if(it)
  226. {
  227. snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
  228. it->name.len, it->name.s);
  229. } else {
  230. snprintf(buf, 512, "sip:%.*s@%.*s", puri.user.len, puri.user.s,
  231. puri.host.len, puri.host.s);
  232. }
  233. }
  234. return buf;
  235. }
  236. char *extract_domain(char *jid)
  237. {
  238. char *p;
  239. if ((p = strchr(jid, '/')))
  240. *p = 0;
  241. if ((p = strchr(jid, '@'))) {
  242. *p++ = 0;
  243. return p;
  244. }
  245. return p;
  246. }
  247. char *random_secret(void)
  248. {
  249. static char secret[41];
  250. int i, r;
  251. for (i = 0; i < 40; i++) {
  252. r = (int) (36.0 * rand() / RAND_MAX);
  253. secret[i] = (r >= 0 && r <= 9) ? (r + 48) : (r + 87);
  254. }
  255. secret[40] = '\0';
  256. return secret;
  257. }
  258. char *db_key(char *secret, char *domain, char *id)
  259. {
  260. char buf[1024];
  261. char *hash;
  262. snprintf(buf, sizeof(buf), "%s", secret);
  263. hash = shahash(buf);
  264. snprintf(buf, sizeof(buf), "%s%s", hash, domain);
  265. hash = shahash(buf);
  266. snprintf(buf, sizeof(buf), "%s%s", hash, id);
  267. hash = shahash(buf);
  268. return hash;
  269. }