00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037
00038 #include "../../sr_module.h"
00039 #include "../../error.h"
00040 #include "../../dprint.h"
00041 #include "../../config.h"
00042 #include "../../pvar.h"
00043 #include "../../radius.h"
00044 #include "../../mem/mem.h"
00045 #include "authrad_mod.h"
00046 #include "authorize.h"
00047 #include "extra.h"
00048
00049 MODULE_VERSION
00050
00051 struct attr attrs[A_MAX+MAX_EXTRA];
00052 struct val vals[V_MAX+MAX_EXTRA];
00053 void *rh;
00054
00055 auth_api_t auth_api;
00056
00057 static int mod_init(void);
00058 static int auth_fixup(void** param, int param_no);
00059
00060
00061
00062
00063
00064 static char* radius_config = DEFAULT_RADIUSCLIENT_CONF;
00065 static int service_type = -1;
00066
00067 int use_ruri_flag = -1;
00068
00069 static char *auth_extra_str = 0;
00070 struct extra_attr *auth_extra = 0;
00071
00072
00073
00074
00075 static cmd_export_t cmds[] = {
00076 {"radius_www_authorize", (cmd_function)radius_www_authorize, 1, auth_fixup,
00077 0, REQUEST_ROUTE},
00078 {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_1, 1, auth_fixup,
00079 0, REQUEST_ROUTE},
00080 {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_2, 2, auth_fixup,
00081 0, REQUEST_ROUTE},
00082 {0, 0, 0, 0, 0, 0}
00083 };
00084
00085
00086
00087
00088
00089 static param_export_t params[] = {
00090 {"radius_config", STR_PARAM, &radius_config },
00091 {"service_type", INT_PARAM, &service_type },
00092 {"use_ruri_flag", INT_PARAM, &use_ruri_flag },
00093 {"auth_extra", STR_PARAM, &auth_extra_str },
00094 {0, 0, 0}
00095 };
00096
00097
00098
00099
00100
00101 struct module_exports exports = {
00102 "auth_radius",
00103 DEFAULT_DLFLAGS,
00104 cmds,
00105 params,
00106 0,
00107 0,
00108 0,
00109 0,
00110 mod_init,
00111 0,
00112 0,
00113 0
00114 };
00115
00116
00117
00118
00119
00120 static int mod_init(void)
00121 {
00122 DICT_VENDOR *vend;
00123 bind_auth_t bind_auth;
00124 int n;
00125
00126 if ((rh = rc_read_config(radius_config)) == NULL) {
00127 LM_ERR("failed to open configuration file \n");
00128 return -1;
00129 }
00130
00131 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
00132 LM_ERR("failed to open dictionary file \n");
00133 return -2;
00134 }
00135
00136 bind_auth = (bind_auth_t)find_export("bind_auth", 0, 0);
00137 if (!bind_auth) {
00138 LM_ERR("unable to find bind_auth function. Check if you load the auth module.\n");
00139 return -1;
00140 }
00141
00142 if (bind_auth(&auth_api) < 0) {
00143 LM_ERR("cannot bind to auth module\n");
00144 return -4;
00145 }
00146
00147
00148 init_extra_engine();
00149
00150
00151 if (auth_extra_str &&
00152 (auth_extra=parse_extra_str(auth_extra_str)) == 0 ) {
00153 LM_ERR("failed to parse auth_extra parameter\n");
00154 return -1;
00155 }
00156
00157 memset(attrs, 0, sizeof(attrs));
00158 attrs[A_SERVICE_TYPE].n = "Service-Type";
00159 attrs[A_SIP_URI_USER].n = "Sip-URI-User";
00160 attrs[A_DIGEST_RESPONSE].n = "Digest-Response";
00161 attrs[A_DIGEST_ALGORITHM].n = "Digest-Algorithm";
00162 attrs[A_DIGEST_BODY_DIGEST].n = "Digest-Body-Digest";
00163 attrs[A_DIGEST_CNONCE].n = "Digest-CNonce";
00164 attrs[A_DIGEST_NONCE_COUNT].n = "Digest-Nonce-Count";
00165 attrs[A_DIGEST_QOP].n = "Digest-QOP";
00166 attrs[A_DIGEST_METHOD].n = "Digest-Method";
00167 attrs[A_DIGEST_URI].n = "Digest-URI";
00168 attrs[A_DIGEST_NONCE].n = "Digest-Nonce";
00169 attrs[A_DIGEST_REALM].n = "Digest-Realm";
00170 attrs[A_DIGEST_USER_NAME].n = "Digest-User-Name";
00171 attrs[A_USER_NAME].n = "User-Name";
00172 attrs[A_SIP_AVP].n = "SIP-AVP";
00173 vend = rc_dict_findvend(rh, "Cisco");
00174 if (vend == NULL) {
00175 LM_DBG("no `Cisco' vendor in Radius dictionary\n");
00176 } else {
00177 attrs[A_CISCO_AVPAIR].n = "Cisco-AVPair";
00178 }
00179 n = A_MAX;
00180 n += extra2attrs(auth_extra, attrs, n);
00181 memset(vals, 0, sizeof(vals));
00182 vals[V_SIP_SESSION].n = "Sip-Session";
00183 INIT_AV(rh, attrs, n, vals, V_MAX, "auth_radius", -5, -6);
00184
00185 if (service_type != -1) {
00186 vals[V_SIP_SESSION].v = service_type;
00187 }
00188
00189 return 0;
00190 }
00191
00192
00193
00194
00195
00196 static int auth_fixup(void** param, int param_no)
00197 {
00198 pv_elem_t *model;
00199 str s;
00200 pv_spec_t *sp;
00201
00202 if (param_no == 1) {
00203 s.s = (char*)*param;
00204 if (s.s==0 || s.s[0]==0) {
00205 model = 0;
00206 } else {
00207 s.len = strlen(s.s);
00208 if (pv_parse_format(&s,&model)<0) {
00209 LM_ERR("pv_parse_format failed\n");
00210 return E_OUT_OF_MEM;
00211 }
00212 }
00213 *param = (void*)model;
00214 }
00215
00216 if (param_no == 2) {
00217 sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
00218 if (sp == 0) {
00219 LM_ERR("no pkg memory left\n");
00220 return -1;
00221 }
00222 s.s = (char*)*param;
00223 s.len = strlen(s.s);
00224 if (pv_parse_spec(&s, sp) == 0) {
00225 LM_ERR("parsing of pseudo variable %s failed!\n", (char*)*param);
00226 pkg_free(sp);
00227 return -1;
00228 }
00229 if (sp->type == PVT_NULL) {
00230 LM_ERR("bad pseudo variable\n");
00231 pkg_free(sp);
00232 return -1;
00233 }
00234 *param = (void*)sp;
00235 }
00236
00237 return 0;
00238 }