authrad_mod.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * $Id$
  3. *
  4. * Digest Authentication - Radius support
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of Kamailio, a free SIP server.
  9. *
  10. * Kamailio 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. * Kamailio is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * History:
  25. * -------
  26. * 2003-03-09: Based on auth_mod.c from radius_auth (janakj)
  27. * 2003-03-11: New module interface (janakj)
  28. * 2003-03-16: flags export parameter added (janakj)
  29. * 2003-03-19: all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
  30. * 2006-03-01: pseudo variables support for domain name (bogdan)
  31. */
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include "../../sr_module.h"
  36. #include "../../error.h"
  37. #include "../../dprint.h"
  38. #include "../../config.h"
  39. #include "../../pvar.h"
  40. #include "../../lib/kcore/radius.h"
  41. #include "../../mem/mem.h"
  42. #include "authrad_mod.h"
  43. #include "authorize.h"
  44. #include "extra.h"
  45. MODULE_VERSION
  46. struct attr attrs[A_MAX+MAX_EXTRA];
  47. struct val vals[V_MAX+MAX_EXTRA];
  48. void *rh;
  49. auth_api_s_t auth_api;
  50. static int mod_init(void); /* Module initialization function */
  51. static int auth_fixup(void** param, int param_no); /* char* -> str* */
  52. /*
  53. * Module parameter variables
  54. */
  55. static char* radius_config = DEFAULT_RADIUSCLIENT_CONF;
  56. static int service_type = -1;
  57. int use_ruri_flag = -1;
  58. static char *auth_extra_str = 0;
  59. struct extra_attr *auth_extra = 0;
  60. /*
  61. * Exported functions
  62. */
  63. static cmd_export_t cmds[] = {
  64. {"radius_www_authorize", (cmd_function)radius_www_authorize_1, 1, auth_fixup,
  65. 0, REQUEST_ROUTE},
  66. {"radius_www_authorize", (cmd_function)radius_www_authorize_2, 2, auth_fixup,
  67. 0, REQUEST_ROUTE},
  68. {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_1, 1, auth_fixup,
  69. 0, REQUEST_ROUTE},
  70. {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_2, 2, auth_fixup,
  71. 0, REQUEST_ROUTE},
  72. {0, 0, 0, 0, 0, 0}
  73. };
  74. /*
  75. * Exported parameters
  76. */
  77. static param_export_t params[] = {
  78. {"radius_config", PARAM_STRING, &radius_config },
  79. {"service_type", INT_PARAM, &service_type },
  80. {"use_ruri_flag", INT_PARAM, &use_ruri_flag },
  81. {"auth_extra", PARAM_STRING, &auth_extra_str },
  82. {0, 0, 0}
  83. };
  84. /*
  85. * Module interface
  86. */
  87. struct module_exports exports = {
  88. "auth_radius",
  89. DEFAULT_DLFLAGS, /* dlopen flags */
  90. cmds, /* Exported functions */
  91. params, /* Exported parameters */
  92. 0, /* exported statistics */
  93. 0, /* exported MI functions */
  94. 0, /* exported pseudo-variables */
  95. 0, /* extra processes */
  96. mod_init, /* module initialization function */
  97. 0, /* response function */
  98. 0, /* destroy function */
  99. 0 /* child initialization function */
  100. };
  101. /*
  102. * Module initialization function
  103. */
  104. static int mod_init(void)
  105. {
  106. DICT_VENDOR *vend;
  107. bind_auth_s_t bind_auth;
  108. int n;
  109. if ((rh = rc_read_config(radius_config)) == NULL) {
  110. LM_ERR("failed to open configuration file \n");
  111. return -1;
  112. }
  113. if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
  114. LM_ERR("failed to open dictionary file \n");
  115. return -2;
  116. }
  117. bind_auth = (bind_auth_s_t)find_export("bind_auth_s", 0, 0);
  118. if (!bind_auth) {
  119. LM_ERR("unable to find bind_auth function. Check if you load the auth module.\n");
  120. return -1;
  121. }
  122. if (bind_auth(&auth_api) < 0) {
  123. LM_ERR("cannot bind to auth module\n");
  124. return -4;
  125. }
  126. /* init the extra engine */
  127. init_extra_engine();
  128. /* parse extra attributes (if any) */
  129. if (auth_extra_str &&
  130. (auth_extra=parse_extra_str(auth_extra_str)) == 0 ) {
  131. LM_ERR("failed to parse auth_extra parameter\n");
  132. return -1;
  133. }
  134. memset(attrs, 0, sizeof(attrs));
  135. attrs[A_SERVICE_TYPE].n = "Service-Type";
  136. attrs[A_SIP_URI_USER].n = "Sip-URI-User";
  137. attrs[A_DIGEST_RESPONSE].n = "Digest-Response";
  138. attrs[A_DIGEST_ALGORITHM].n = "Digest-Algorithm";
  139. attrs[A_DIGEST_BODY_DIGEST].n = "Digest-Body-Digest";
  140. attrs[A_DIGEST_CNONCE].n = "Digest-CNonce";
  141. attrs[A_DIGEST_NONCE_COUNT].n = "Digest-Nonce-Count";
  142. attrs[A_DIGEST_QOP].n = "Digest-QOP";
  143. attrs[A_DIGEST_METHOD].n = "Digest-Method";
  144. attrs[A_DIGEST_URI].n = "Digest-URI";
  145. attrs[A_DIGEST_NONCE].n = "Digest-Nonce";
  146. attrs[A_DIGEST_REALM].n = "Digest-Realm";
  147. attrs[A_DIGEST_USER_NAME].n = "Digest-User-Name";
  148. attrs[A_USER_NAME].n = "User-Name";
  149. attrs[A_SIP_AVP].n = "SIP-AVP";
  150. vend = rc_dict_findvend(rh, "Cisco");
  151. if (vend == NULL) {
  152. LM_DBG("no `Cisco' vendor in Radius dictionary\n");
  153. } else {
  154. attrs[A_CISCO_AVPAIR].n = "Cisco-AVPair";
  155. }
  156. n = A_MAX;
  157. n += extra2attrs(auth_extra, attrs, n);
  158. memset(vals, 0, sizeof(vals));
  159. vals[V_SIP_SESSION].n = "Sip-Session";
  160. INIT_AV(rh, attrs, n, vals, V_MAX, "auth_radius", -5, -6);
  161. if (service_type != -1) {
  162. vals[V_SIP_SESSION].v = service_type;
  163. }
  164. return 0;
  165. }
  166. /*
  167. * Convert char* parameter to pv_elem_t* parameter
  168. */
  169. static int auth_fixup(void** param, int param_no)
  170. {
  171. pv_elem_t *model;
  172. str s;
  173. pv_spec_t *sp;
  174. if (param_no == 1) { /* realm (string that may contain pvars) */
  175. s.s = (char*)*param;
  176. if (s.s==0 || s.s[0]==0) {
  177. model = 0;
  178. } else {
  179. s.len = strlen(s.s);
  180. if (pv_parse_format(&s,&model)<0) {
  181. LM_ERR("pv_parse_format failed\n");
  182. return E_OUT_OF_MEM;
  183. }
  184. }
  185. *param = (void*)model;
  186. }
  187. if (param_no == 2) { /* URI user (a pvar) */
  188. sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
  189. if (sp == 0) {
  190. LM_ERR("no pkg memory left\n");
  191. return -1;
  192. }
  193. s.s = (char*)*param;
  194. s.len = strlen(s.s);
  195. if (pv_parse_spec(&s, sp) == 0) {
  196. LM_ERR("parsing of pseudo variable %s failed!\n", (char*)*param);
  197. pkg_free(sp);
  198. return -1;
  199. }
  200. if (sp->type == PVT_NULL) {
  201. LM_ERR("bad pseudo variable\n");
  202. pkg_free(sp);
  203. return -1;
  204. }
  205. *param = (void*)sp;
  206. }
  207. return 0;
  208. }