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 #ifdef RADIUSCLIENT_NG_4
00030 # include <radiusclient.h>
00031 # else
00032 # include <radiusclient-ng.h>
00033 #endif
00034
00035 #include "../../rad_dict.h"
00036 #include "../../sr_module.h"
00037 #include "../../mem/mem.h"
00038 #include "../../parser/digest/digest_parser.h"
00039 #include "../../parser/digest/digest.h"
00040 #include "../../parser/parse_uri.h"
00041 #include "../../parser/parse_from.h"
00042 #include "../domain/domain.h"
00043 #include "../../usr_avp.h"
00044 #include "../../ut.h"
00045 #include "../../config.h"
00046
00047
00048 MODULE_VERSION
00049
00050
00051 static int mod_init(void);
00052 static int radius_load_attrs(struct sip_msg*, char*, char*);
00053 static int attrs_fixup(void**, int);
00054
00055 static char *radius_config = "/usr/local/etc/radiusclient/radiusclient.conf";
00056
00057 static void *rh;
00058 struct attr attrs[A_MAX];
00059 struct val vals[V_MAX];
00060
00061 static domain_get_did_t dm_get_did = NULL;
00062
00063
00064
00065
00066
00067 static cmd_export_t cmds[] = {
00068 {"radius_load_attrs", radius_load_attrs, 2, attrs_fixup, REQUEST_ROUTE | FAILURE_ROUTE},
00069 {0, 0, 0, 0, 0}
00070 };
00071
00072
00073
00074
00075
00076 static param_export_t params[] = {
00077 {"radius_config", PARAM_STRING, &radius_config },
00078 {0, 0, 0}
00079 };
00080
00081
00082 struct module_exports exports = {
00083 "avp_radius",
00084 cmds,
00085 0,
00086 params,
00087 mod_init,
00088 0,
00089 0,
00090 0,
00091 0
00092 };
00093
00094
00095 static int mod_init(void)
00096 {
00097 DICT_VENDOR *vend;
00098 memset(attrs, 0, sizeof(attrs));
00099 memset(vals, 0, sizeof(vals));
00100
00101 attrs[A_USER_NAME].n = "User-Name";
00102 attrs[A_SER_SERVICE_TYPE].n = "SER-Service-Type";
00103 attrs[A_SER_ATTR].n = "SER-Attr";
00104 attrs[A_SER_DID].n = "SER-DID";
00105 attrs[A_SER_URI_SCHEME].n = "SER-Uri-Scheme";
00106
00107 vals[V_GET_URI_ATTRS].n = "Get-URI-Attrs";
00108 vals[V_GET_USER_ATTRS].n = "Get-User-Attrs";
00109
00110
00111 rc_openlog("ser");
00112
00113
00114 if ((rh = rc_read_config(radius_config)) == NULL) {
00115 LOG(L_ERR, "avp_radius: Error opening radius config file: %s\n",
00116 radius_config);
00117 return -1;
00118 }
00119
00120
00121 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
00122 LOG(L_ERR, "avp_radius: Error reading radius dictionary\n");
00123 return -1;
00124 }
00125
00126 vend = rc_dict_findvend(rh, "iptelorg");
00127 if (vend == NULL) {
00128 ERR("RADIUS dictionary is missing required vendor 'iptelorg'\n");
00129 return -1;
00130 }
00131
00132 INIT_AV(rh, attrs, vals, "avp", -1, -1);
00133 return 0;
00134 }
00135
00136
00137 static void attr_name_value(str* name, str* value, VALUE_PAIR* vp)
00138 {
00139 int i;
00140
00141 for (i = 0; i < vp->lvalue; i++) {
00142 if (vp->strvalue[i] == ':' || vp->strvalue[i] == '=') {
00143 name->s = vp->strvalue;
00144 name->len = i;
00145
00146 if (i == (vp->lvalue - 1)) {
00147 value->s = (char*)0;
00148 value->len = 0;
00149 } else {
00150 value->s = vp->strvalue + i + 1;
00151 value->len = vp->lvalue - i - 1;
00152 }
00153 return;
00154 }
00155 }
00156
00157 name->len = value->len = 0;
00158 name->s = value->s = (char*)0;
00159 }
00160
00161
00162
00163
00164
00165 static int generate_avps(unsigned int flags, VALUE_PAIR* received)
00166 {
00167 int_str name, val;
00168 VALUE_PAIR *vp;
00169
00170 vp = received;
00171 while ((vp = rc_avpair_get(vp, ATTRID(attrs[A_SER_ATTR].v), VENDOR(attrs[A_SER_ATTR].v)))) {
00172 attr_name_value(&name.s, &val.s, vp);
00173 if (name.s.len == 0) {
00174 ERR("Missing attribute name\n");
00175 return -1;
00176 }
00177
00178 if (add_avp(flags | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) {
00179 ERR("Unable to create a new SER attribute\n");
00180 return -1;
00181 }
00182 vp = vp->next;
00183 }
00184
00185 return 0;
00186 }
00187
00188
00189 static int load_user_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
00190 {
00191 static char rad_msg[4096];
00192 str uid;
00193 UINT4 service;
00194 VALUE_PAIR* send, *received;
00195
00196 send = NULL;
00197 received = NULL;
00198
00199 if (get_str_fparam(&uid, msg, (fparam_t*)fp) < 0) {
00200 ERR("Unable to get UID\n");
00201 return -1;
00202 }
00203
00204 service = vals[V_GET_USER_ATTRS].v;
00205
00206 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v),
00207 uid.s, uid.len,
00208 VENDOR(attrs[A_USER_NAME].v))) {
00209 ERR("Error while adding A_USER_NAME\n");
00210 goto error;
00211 }
00212
00213 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v),
00214 &vals[V_GET_USER_ATTRS].v, -1,
00215 VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
00216 ERR("Error adding A_SERVICE_TYPE\n");
00217 goto error;
00218 }
00219
00220
00221 if (rc_auth(rh, 0, send, &received, rad_msg) != OK_RC) {
00222 DBG("load_user_attrs: Failure\n");
00223 goto error;
00224 }
00225
00226 DBG("load_user_attrs: Success\n");
00227 rc_avpair_free(send);
00228
00229 if (generate_avps(flags, received) < 0) {
00230 rc_avpair_free(received);
00231 goto error;
00232 }
00233
00234 rc_avpair_free(received);
00235 return 1;
00236
00237 error:
00238 if (send) rc_avpair_free(send);
00239 if (received) rc_avpair_free(send);
00240 return -1;
00241 }
00242
00243
00244 static int load_uri_attrs(struct sip_msg* msg, unsigned long flags, fparam_t* fp)
00245 {
00246 static char rad_msg[4096];
00247 struct sip_uri puri;
00248 str uri, did, scheme;
00249 UINT4 service;
00250 VALUE_PAIR* send, *received;
00251
00252 send = NULL;
00253 received = NULL;
00254
00255 if (get_str_fparam(&uri, msg, (fparam_t*)fp) != 0) {
00256 ERR("Unable to get URI\n");
00257 return -1;
00258 }
00259
00260 if (parse_uri(uri.s, uri.len, &puri) < 0) {
00261 ERR("Error while parsing URI '%.*s'\n", uri.len, uri.s);
00262 return -1;
00263 }
00264
00265 if (puri.host.len) {
00266
00267 if (dm_get_did(&did, &puri.host) < 0) {
00268 DBG("Cannot lookup DID for domain %.*s, using default value\n", puri.host.len, ZSW(puri.host.s));
00269 did.s = DEFAULT_DID;
00270 did.len = sizeof(DEFAULT_DID) - 1;
00271 }
00272 } else {
00273
00274 DBG("There is no domain name, using default value\n");
00275 did.s = DEFAULT_DID;
00276 did.len = sizeof(DEFAULT_DID) - 1;
00277 }
00278
00279 uri_type_to_str(puri.type, &scheme);
00280 service = vals[V_GET_URI_ATTRS].v;
00281
00282 if (scheme.len) {
00283 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_URI_SCHEME].v),
00284 scheme.s, scheme.len,
00285 VENDOR(attrs[A_SER_URI_SCHEME].v))) {
00286 ERR("Error while adding A_SER_URI_SCHEME\n");
00287 goto error;
00288 }
00289 }
00290
00291 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_USER_NAME].v),
00292 puri.user.s, puri.user.len,
00293 VENDOR(attrs[A_USER_NAME].v))) {
00294 ERR("Error while adding A_USER_NAME\n");
00295 goto error;
00296 }
00297
00298 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_DID].v),
00299 did.s, did.len,
00300 VENDOR(attrs[A_SER_DID].v))) {
00301 ERR("Error while adding A_SER_DID\n");
00302 goto error;
00303 }
00304
00305 if (!rc_avpair_add(rh, &send, ATTRID(attrs[A_SER_SERVICE_TYPE].v),
00306 &vals[V_GET_URI_ATTRS].v, -1,
00307 VENDOR(attrs[A_SER_SERVICE_TYPE].v))) {
00308 ERR("Error adding A_SERVICE_TYPE\n");
00309 goto error;
00310 }
00311
00312 if (rc_auth(rh, 0, send, &received, rad_msg) != OK_RC) {
00313 DBG("load_uri_attrs: Failure\n");
00314 goto error;
00315 }
00316
00317 DBG("load_uri_attrs: Success\n");
00318 rc_avpair_free(send);
00319
00320 if (generate_avps(flags, received) < 0) {
00321 rc_avpair_free(received);
00322 goto error;
00323 }
00324
00325 rc_avpair_free(received);
00326 return 1;
00327
00328 error:
00329 if (send) rc_avpair_free(send);
00330 if (received) rc_avpair_free(send);
00331 return -1;
00332 }
00333
00334
00335
00336
00337
00338 static int radius_load_attrs(struct sip_msg* msg, char* fl, char* fp)
00339 {
00340 unsigned long flags;
00341
00342 flags = (unsigned long)fl;
00343
00344 if (flags & AVP_CLASS_URI) {
00345 return load_uri_attrs(msg, flags, (fparam_t*)fp);
00346 } else {
00347 return load_user_attrs(msg, flags, (fparam_t*)fp);
00348 }
00349 }
00350
00351
00352 static int attrs_fixup(void** param, int param_no)
00353 {
00354 unsigned long flags;
00355 char* s;
00356
00357 if (param_no == 1) {
00358
00359 s = (char*)*param;
00360 flags = 0;
00361 if (*s != '$' || (strlen(s) != 3)) {
00362 ERR("Invalid parameter value, $xy expected\n");
00363 return -1;
00364 }
00365 switch((s[1] << 8) + s[2]) {
00366 case 0x4655:
00367 case 0x6675:
00368 case 0x4675:
00369 case 0x6655:
00370 flags = AVP_TRACK_FROM | AVP_CLASS_USER;
00371 break;
00372
00373 case 0x4652:
00374 case 0x6672:
00375 case 0x4672:
00376 case 0x6652:
00377 flags = AVP_TRACK_FROM | AVP_CLASS_URI;
00378 break;
00379
00380 case 0x5455:
00381 case 0x7475:
00382 case 0x5475:
00383 case 0x7455:
00384 flags = AVP_TRACK_TO | AVP_CLASS_USER;
00385 break;
00386
00387 case 0x5452:
00388 case 0x7472:
00389 case 0x5472:
00390 case 0x7452:
00391 flags = AVP_TRACK_TO | AVP_CLASS_URI;
00392 break;
00393
00394 default:
00395 ERR("Invalid parameter value: '%s'\n", s);
00396 return -1;
00397 }
00398
00399 if ((flags & AVP_CLASS_URI) && !dm_get_did) {
00400 dm_get_did = (domain_get_did_t)find_export("get_did", 0, 0);
00401 if (!dm_get_did) {
00402 ERR("Domain module required but not found\n");
00403 return -1;
00404 }
00405 }
00406
00407 pkg_free(*param);
00408 *param = (void*)flags;
00409 } else if (param_no == 2) {
00410 return fixup_var_str_12(param, 2);
00411 }
00412 return 0;
00413 }