verify.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * Verification functions
  3. *
  4. * Copyright (C) 2008 Juha Heinanen
  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
  21. * USA.
  22. *
  23. */
  24. /*! \file
  25. * \ingroup peering
  26. * \brief Verification functions
  27. *
  28. * - Module: \ref peering
  29. */
  30. #include "../../str.h"
  31. #include "../../lib/kcore/radius.h"
  32. #include "../../usr_avp.h"
  33. #include "../../dprint.h"
  34. #include "../../ut.h"
  35. #include "../../lib/kcore/radius.h"
  36. #include "../../lib/kcore/cmpapi.h"
  37. #include "../../parser/parse_uri.h"
  38. #include "../../parser/parse_from.h"
  39. #include "peering.h"
  40. /*
  41. * Extract name and value of an AVP from VALUE_PAIR
  42. */
  43. static inline int extract_avp(VALUE_PAIR* vp, unsigned short *flags,
  44. int_str *name, int_str *value)
  45. {
  46. static str names, values;
  47. unsigned int r;
  48. char *p;
  49. char *end;
  50. /* empty? */
  51. if (vp->lvalue==0 || vp->strvalue==0)
  52. goto error;
  53. p = vp->strvalue;
  54. end = vp->strvalue + vp->lvalue;
  55. /* get name */
  56. if (*p!='#') {
  57. /* name AVP */
  58. *flags |= AVP_NAME_STR;
  59. names.s = p;
  60. } else {
  61. names.s = ++p;
  62. }
  63. names.len = 0;
  64. while( p<end && *p!=':' && *p!='#')
  65. p++;
  66. if (names.s==p || p==end) {
  67. LM_ERR("empty AVP name\n");
  68. goto error;
  69. }
  70. names.len = p - names.s;
  71. LM_DBG("AVP name is <%.*s>\n", names.len, names.s);
  72. /* get value */
  73. if (*p!='#') {
  74. /* string value */
  75. *flags |= AVP_VAL_STR;
  76. }
  77. values.s = ++p;
  78. values.len = end-values.s;
  79. if (values.len==0) {
  80. LM_ERR("Empty AVP value\n");
  81. goto error;
  82. }
  83. LM_DBG("AVP val is <%.*s>\n", values.len, values.s);
  84. if ( !((*flags)&AVP_NAME_STR) ) {
  85. /* convert name to id*/
  86. if (str2int(&names,&r)!=0 ) {
  87. LM_ERR("invalid AVP ID '%.*s'\n", names.len,names.s);
  88. goto error;
  89. }
  90. name->n = (int)r;
  91. } else {
  92. name->s = names;
  93. }
  94. if ( !((*flags)&AVP_VAL_STR) ) {
  95. /* convert value to integer */
  96. if (str2int(&values,&r)!=0 ) {
  97. LM_ERR("invalid AVP numerical value '%.*s'\n",
  98. values.len,values.s);
  99. goto error;
  100. }
  101. value->n = (int)r;
  102. } else {
  103. value->s = values;
  104. }
  105. return 0;
  106. error:
  107. return -1;
  108. }
  109. /*
  110. * Generate AVPs from result of Radius query
  111. */
  112. static int generate_avps(VALUE_PAIR* received)
  113. {
  114. int_str name, val;
  115. unsigned short flags;
  116. VALUE_PAIR *vp;
  117. vp = received;
  118. LM_DBG("getting SIP AVPs from avpair %d\n", attrs[A_SIP_AVP].v);
  119. for(; (vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0)); vp=vp->next) {
  120. flags = 0;
  121. if (extract_avp(vp, &flags, &name, &val) != 0)
  122. continue;
  123. if (add_avp( flags, name, val) < 0) {
  124. LM_ERR("unable to add a new AVP\n");
  125. } else {
  126. LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
  127. (flags&AVP_NAME_STR)?name.s.len:4,
  128. (flags&AVP_NAME_STR)?name.s.s:"null",
  129. (flags&AVP_NAME_STR)?0:name.n,
  130. (flags&AVP_VAL_STR)?val.s.len:4,
  131. (flags&AVP_VAL_STR)?val.s.s:"null",
  132. (flags&AVP_VAL_STR)?0:val.n );
  133. }
  134. }
  135. return 0;
  136. }
  137. /*
  138. * Send Radius request to verify destination and generate AVPs from
  139. * reply items of positive response.
  140. */
  141. int verify_destination(struct sip_msg* _msg, char* s1, char* s2)
  142. {
  143. VALUE_PAIR* send, *received;
  144. uint32_t service;
  145. static char rad_msg[4096];
  146. int i;
  147. send = received = 0;
  148. /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
  149. if (parse_sip_msg_uri(_msg) < 0) {
  150. LM_ERR("error while parsing Request-URI\n");
  151. return -1;
  152. }
  153. if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
  154. _msg->parsed_uri.host.s,
  155. _msg->parsed_uri.host.len, 0)) {
  156. LM_ERR("error adding PW_USER_NAME\n");
  157. goto err;
  158. }
  159. if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v,
  160. _msg->parsed_uri.user.s,
  161. _msg->parsed_uri.user.len, 0)) {
  162. LM_ERR("error adding PW_SIP_URI_USER\n");
  163. goto err;
  164. }
  165. /* Add From Tag */
  166. if (parse_from_header(_msg) < 0) {
  167. LM_ERR("error while parsing From header field\n");
  168. goto err;
  169. }
  170. if ((_msg->from==NULL) || (get_from(_msg) == NULL) ||
  171. (get_from(_msg)->tag_value.s == NULL) ||
  172. (get_from(_msg)->tag_value.len <= 0)) {
  173. LM_ERR("error while accessing From header tag\n");
  174. goto err;
  175. }
  176. if (!rc_avpair_add(rh, &send, attrs[A_SIP_FROM_TAG].v,
  177. get_from(_msg)->tag_value.s,
  178. get_from(_msg)->tag_value.len, 0)) {
  179. LM_ERR("error adding PW_SIP_FROM_TAG\n");
  180. goto err;
  181. }
  182. /* Add Call-Id */
  183. if ((parse_headers(_msg, HDR_CALLID_F, 0) == -1) ||
  184. (_msg->callid == NULL) || (_msg->callid->body.s == NULL) ||
  185. (_msg->callid->body.len <= 0)) {
  186. LM_ERR("error while accessing Call-Id\n");
  187. goto err;
  188. }
  189. if (!rc_avpair_add(rh, &send, attrs[A_SIP_CALL_ID].v,
  190. _msg->callid->body.s,
  191. _msg->callid->body.len, 0)) {
  192. LM_ERR("error adding PW_SIP_CALL_ID\n");
  193. goto err;
  194. }
  195. /* Add Service-Type */
  196. service = vals[V_SIP_VERIFY_DESTINATION].v;
  197. if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v,
  198. &service, -1, 0)) {
  199. LM_ERR("error adding PW_SERVICE_TYPE\n");
  200. goto err;
  201. }
  202. /* Send Request and generate AVPs of positive reply */
  203. if ((i = rc_auth(rh, SIP_PORT, send, &received, rad_msg)) == OK_RC) {
  204. LM_DBG("success\n");
  205. rc_avpair_free(send);
  206. generate_avps(received);
  207. rc_avpair_free(received);
  208. return 1;
  209. } else {
  210. #ifdef REJECT_RC
  211. if (i == REJECT_RC) {
  212. LM_DBG("rejected\n");
  213. } else {
  214. LM_ERR("failure\n");
  215. }
  216. goto err;
  217. #else
  218. LM_DBG("failure\n");
  219. goto err;
  220. #endif
  221. }
  222. err:
  223. if (send) rc_avpair_free(send);
  224. if (received) rc_avpair_free(received);
  225. return -1;
  226. }
  227. /*
  228. * Send Radius request to verify source.
  229. */
  230. int verify_source(struct sip_msg* _msg, char* s1, char* s2)
  231. {
  232. VALUE_PAIR* send, *received;
  233. struct hdr_field *hf;
  234. uint32_t service;
  235. static char rad_msg[4096];
  236. int i;
  237. send = received = 0;
  238. /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
  239. if (parse_sip_msg_uri(_msg) < 0) {
  240. LM_ERR("error while parsing Request-URI\n");
  241. return -1;
  242. }
  243. if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
  244. _msg->parsed_uri.host.s,
  245. _msg->parsed_uri.host.len, 0)) {
  246. LM_ERR("error adding PW_USER_NAME\n");
  247. goto err;
  248. }
  249. if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v,
  250. _msg->parsed_uri.user.s,
  251. _msg->parsed_uri.user.len, 0)) {
  252. LM_ERR("error adding PW_SIP_URI_USER\n");
  253. goto err;
  254. }
  255. /* Add From Tag */
  256. if (parse_from_header(_msg) < 0) {
  257. LM_ERR("error while parsing From header field\n");
  258. goto err;
  259. }
  260. if ((_msg->from==NULL) || (get_from(_msg) == NULL) ||
  261. (get_from(_msg)->tag_value.s == NULL) ||
  262. (get_from(_msg)->tag_value.len <= 0)) {
  263. LM_ERR("error while accessing From header tag\n");
  264. goto err;
  265. }
  266. if (!rc_avpair_add(rh, &send, attrs[A_SIP_FROM_TAG].v,
  267. get_from(_msg)->tag_value.s,
  268. get_from(_msg)->tag_value.len, 0)) {
  269. LM_ERR("error adding PW_SIP_FROM_TAG\n");
  270. goto err;
  271. }
  272. /* Add Call-Id */
  273. if ((parse_headers(_msg, HDR_CALLID_F, 0) == -1) ||
  274. (_msg->callid == NULL) || (_msg->callid->body.s == NULL) ||
  275. (_msg->callid->body.len <= 0)) {
  276. LM_ERR("error while accessing Call-Id\n");
  277. goto err;
  278. }
  279. if (!rc_avpair_add(rh, &send, attrs[A_SIP_CALL_ID].v,
  280. _msg->callid->body.s,
  281. _msg->callid->body.len, 0)) {
  282. LM_ERR("error adding PW_SIP_CALL_ID\n");
  283. goto err;
  284. }
  285. /* Add P-Request-Hash header body */
  286. parse_headers(_msg, HDR_EOH_F, 0);
  287. for (hf = _msg->headers; hf; hf = hf->next) {
  288. if(cmp_hdrname_strzn(&hf->name, "P-Request-Hash",
  289. sizeof("P-Request-Hash") - 1) == 0)
  290. break;
  291. }
  292. if (!hf) {
  293. LM_ERR("no P-Request-Hash header field\n");
  294. goto err;
  295. }
  296. if ((hf->body.s == NULL) || (hf->body.len <= 0)) {
  297. LM_ERR("error while accessing P-Request-Hash body\n");
  298. goto err;
  299. }
  300. if (!rc_avpair_add(rh, &send, attrs[A_SIP_REQUEST_HASH].v,
  301. hf->body.s, hf->body.len, 0)) {
  302. LM_ERR("error adding PW_SIP_REQUEST_HASH\n");
  303. goto err;
  304. }
  305. /* Add Service-Type */
  306. service = vals[V_SIP_VERIFY_SOURCE].v;
  307. if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v,
  308. &service, -1, 0)) {
  309. LM_ERR("error adding PW_SERVICE_TYPE\n");
  310. goto err;
  311. }
  312. /* Send Request and generate AVPs of positive reply */
  313. if ((i = rc_auth(rh, SIP_PORT, send, &received, rad_msg)) == OK_RC) {
  314. LM_DBG("success\n");
  315. rc_avpair_free(send);
  316. rc_avpair_free(received);
  317. return 1;
  318. } else {
  319. #ifdef REJECT_RC
  320. if (i == REJECT_RC) {
  321. LM_DBG("rejected\n");
  322. } else {
  323. LM_ERR("failure\n");
  324. }
  325. goto err;
  326. #else
  327. LM_DBG("failure\n");
  328. goto err;
  329. #endif
  330. }
  331. err:
  332. if (send) rc_avpair_free(send);
  333. if (received) rc_avpair_free(received);
  334. return -1;
  335. }