mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
781 lines
20 KiB
781 lines
20 KiB
/*
|
|
* functions.c Implementation of exported functions
|
|
*
|
|
* Copyright (C) 2004 FhG Fokus
|
|
* Copyright (C) 2008 Juha Heinanen <jh@tutpro.com>
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* Kamailio is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* Kamailio is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
#include "../../mod_fix.h"
|
|
#include "../../ut.h"
|
|
#include "../../dprint.h"
|
|
#include "../../usr_avp.h"
|
|
#include "../../lib/kcore/radius.h"
|
|
#include "../../parser/parse_uri.h"
|
|
#include "misc_radius.h"
|
|
#include "extra.h"
|
|
|
|
/* Array for extra attribute values */
|
|
static str val_arr[MAX_EXTRA];
|
|
|
|
/* Extract one reply item value to AVP flags, name and value */
|
|
static inline int extract_avp(VALUE_PAIR* vp, unsigned short *flags,
|
|
int_str *name, int_str *value)
|
|
{
|
|
static str names, values;
|
|
unsigned int r;
|
|
char *p;
|
|
char *end;
|
|
|
|
/* empty? */
|
|
if (vp->lvalue==0)
|
|
goto error;
|
|
|
|
p = vp->strvalue;
|
|
end = vp->strvalue + vp->lvalue;
|
|
|
|
/* get name */
|
|
if (*p!='#') {
|
|
/* name AVP */
|
|
*flags |= AVP_NAME_STR;
|
|
names.s = p;
|
|
} else {
|
|
names.s = ++p;
|
|
}
|
|
|
|
names.len = 0;
|
|
while( p<end && *p!=':' && *p!='#')
|
|
p++;
|
|
if (names.s==p || p==end) {
|
|
LM_ERR("empty AVP name\n");
|
|
goto error;
|
|
}
|
|
names.len = p - names.s;
|
|
|
|
/* get value */
|
|
if (*p!='#') {
|
|
/* string value */
|
|
*flags |= AVP_VAL_STR;
|
|
}
|
|
values.s = ++p;
|
|
values.len = end-values.s;
|
|
if (values.len==0) {
|
|
LM_ERR("empty AVP value\n");
|
|
goto error;
|
|
}
|
|
|
|
if ( !((*flags)&AVP_NAME_STR) ) {
|
|
/* convert name to id*/
|
|
if (str2int(&names,&r)!=0 ) {
|
|
LM_ERR("invalid AVP ID '%.*s'\n", names.len,names.s);
|
|
goto error;
|
|
}
|
|
name->n = (int)r;
|
|
} else {
|
|
name->s = names;
|
|
}
|
|
|
|
if ( !((*flags)&AVP_VAL_STR) ) {
|
|
/* convert value to integer */
|
|
if (str2int(&values,&r)!=0 ) {
|
|
LM_ERR("invalid AVP numrical value '%.*s'\n", values.len,values.s);
|
|
goto error;
|
|
}
|
|
value->n = (int)r;
|
|
} else {
|
|
value->s = values;
|
|
}
|
|
|
|
return 0;
|
|
error:
|
|
return -1;
|
|
}
|
|
|
|
static void generate_avps_rad(VALUE_PAIR* received)
|
|
{
|
|
int_str name, val;
|
|
unsigned short flags;
|
|
VALUE_PAIR *vp;
|
|
|
|
vp = received;
|
|
|
|
for( ; vp ; vp=vp->next) {
|
|
flags = AVP_NAME_STR;
|
|
switch(vp->type)
|
|
{
|
|
case PW_TYPE_STRING:
|
|
flags |= AVP_VAL_STR;
|
|
name.s.len = strlen(vp->name);
|
|
val.s.len = strlen(vp->strvalue);
|
|
name.s.s = vp->name;
|
|
val.s.s = vp->strvalue;
|
|
if (add_avp( flags, name, val ) < 0) {
|
|
LM_ERR("unable to create a new AVP\n");
|
|
} else {
|
|
LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
|
|
(flags&AVP_NAME_STR)?name.s.len:4,
|
|
(flags&AVP_NAME_STR)?name.s.s:"null",
|
|
(flags&AVP_NAME_STR)?0:name.n,
|
|
(flags&AVP_VAL_STR)?val.s.len:4,
|
|
(flags&AVP_VAL_STR)?val.s.s:"null",
|
|
(flags&AVP_VAL_STR)?0:val.n );
|
|
}
|
|
continue;
|
|
case PW_TYPE_INTEGER:
|
|
name.s.len = strlen(vp->name);
|
|
name.s.s = vp->name;
|
|
val.n = vp->lvalue;
|
|
if (add_avp( flags, name, val ) < 0) {
|
|
LM_ERR("unable to create a new AVP\n");
|
|
} else {
|
|
LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
|
|
(flags&AVP_NAME_STR)?name.s.len:4,
|
|
(flags&AVP_NAME_STR)?name.s.s:"null",
|
|
(flags&AVP_NAME_STR)?0:name.n,
|
|
(flags&AVP_VAL_STR)?val.s.len:4,
|
|
(flags&AVP_VAL_STR)?val.s.s:"null",
|
|
(flags&AVP_VAL_STR)?0:val.n );
|
|
}
|
|
continue;
|
|
default:
|
|
LM_ERR("skip attribute type %d (non-string)", vp->type);
|
|
continue;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/* Generate AVPs from Radius reply items */
|
|
static void generate_avps(struct attr *attrs, VALUE_PAIR* received)
|
|
{
|
|
int_str name, val;
|
|
unsigned short flags;
|
|
VALUE_PAIR *vp;
|
|
|
|
vp = received;
|
|
|
|
for( ; (vp=rc_avpair_get(vp,attrs[SA_SIP_AVP].v,0)) ; vp=vp->next) {
|
|
flags = 0;
|
|
if (extract_avp( vp, &flags, &name, &val)!=0 )
|
|
continue;
|
|
if (add_avp( flags, name, val) < 0) {
|
|
LM_ERR("unable to create a new AVP\n");
|
|
} else {
|
|
LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
|
|
(flags&AVP_NAME_STR)?name.s.len:4,
|
|
(flags&AVP_NAME_STR)?name.s.s:"null",
|
|
(flags&AVP_NAME_STR)?0:name.n,
|
|
(flags&AVP_VAL_STR)?val.s.len:4,
|
|
(flags&AVP_VAL_STR)?val.s.s:"null",
|
|
(flags&AVP_VAL_STR)?0:val.n );
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/* Macro to add extra attribute */
|
|
#define ADD_EXTRA_AVPAIR(_attrs, _attr, _val, _len) \
|
|
do { \
|
|
if ((_len) != 0) { \
|
|
if ((_len) == -1) { \
|
|
if (_attrs[_attr].t != PW_TYPE_INTEGER) { \
|
|
if (_attrs[_attr].t != PW_TYPE_IPADDR) { \
|
|
LM_ERR("attribute %d is not of type integer or ipaddr\n", \
|
|
_attrs[_attr].v); \
|
|
goto error; \
|
|
} \
|
|
} \
|
|
} \
|
|
if (!rc_avpair_add( rh, &send, _attrs[_attr].v, _val, _len, 0)) { \
|
|
LM_ERR("failed to add %s, %d\n", _attrs[_attr].n, _attr); \
|
|
goto error; \
|
|
} \
|
|
} \
|
|
}while(0)
|
|
|
|
|
|
/*
|
|
* Loads from Radius caller's AVPs based on pvar argument.
|
|
* Returns 1 if Radius request succeeded and -1 otherwise.
|
|
*/
|
|
int radius_load_caller_avps(struct sip_msg* _m, char* _caller, char* _s2)
|
|
{
|
|
str user;
|
|
VALUE_PAIR *send, *received;
|
|
uint32_t service;
|
|
static char msg[4096];
|
|
int extra_cnt, offset, i, res;
|
|
|
|
if ((_caller == NULL) ||
|
|
(fixup_get_svalue(_m, (gparam_p)_caller, &user) != 0)) {
|
|
LM_ERR("invalid caller parameter");
|
|
return -1;
|
|
}
|
|
|
|
send = received = 0;
|
|
|
|
if (!rc_avpair_add(rh, &send, caller_attrs[SA_USER_NAME].v,
|
|
user.s, user.len, 0)) {
|
|
LM_ERR("in adding SA_USER_NAME\n");
|
|
return -1;
|
|
}
|
|
|
|
service = caller_vals[RV_SIP_CALLER_AVPS].v;
|
|
if (!rc_avpair_add(rh, &send, caller_attrs[SA_SERVICE_TYPE].v,
|
|
&service, -1, 0)) {
|
|
LM_ERR("error adding SA_SERVICE_TYPE <%u>\n", service);
|
|
goto error;
|
|
}
|
|
|
|
/* Add extra attributes */
|
|
extra_cnt = extra2strar(caller_extra, _m, val_arr);
|
|
if (extra_cnt == -1) {
|
|
LM_ERR("in getting values of caller extra attributes\n");
|
|
goto error;
|
|
}
|
|
offset = SA_STATIC_MAX;
|
|
for (i = 0; i < extra_cnt; i++) {
|
|
if (val_arr[i].len == -1) {
|
|
/* Add integer attribute */
|
|
ADD_EXTRA_AVPAIR(caller_attrs, offset+i,
|
|
&(val_arr[i].s), val_arr[i].len );
|
|
} else {
|
|
/* Add string attribute */
|
|
ADD_EXTRA_AVPAIR(caller_attrs, offset+i,
|
|
val_arr[i].s, val_arr[i].len );
|
|
}
|
|
}
|
|
|
|
res = rc_auth(rh, 0, send, &received, msg);
|
|
|
|
if (res == OK_RC) {
|
|
LM_DBG("Radius Load Caller Success\n");
|
|
rc_avpair_free(send);
|
|
if (common_response) {
|
|
generate_avps_rad(received);
|
|
} else {
|
|
generate_avps(caller_attrs, received);
|
|
}
|
|
rc_avpair_free(received);
|
|
return 1;
|
|
} else if(res == BADRESP_RC){
|
|
LM_ERR("Authz radius - Load Caller - BAD RESPONSE \n");
|
|
} else if(res == ERROR_RC){
|
|
LM_ERR("Authz radius - Load Caller - ERROR \n");
|
|
} else if(res == TIMEOUT_RC){
|
|
LM_ERR("Authz radius - Load Caller - TIMEOUT \n");
|
|
} else if(res == REJECT_RC){
|
|
LM_ERR("Authz radius - Load Caller - REJECTED \n");
|
|
} else{
|
|
LM_ERR("Authz radius - Load Caller - Unkown Response \n");
|
|
}
|
|
|
|
rc_avpair_free(send);
|
|
|
|
if (common_response){
|
|
generate_avps_rad(received);
|
|
}
|
|
|
|
rc_avpair_free(received);
|
|
return -1;
|
|
|
|
error:
|
|
rc_avpair_free(send);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Loads from Radius callee's AVPs based on pvar argument.
|
|
* Returns 1 if Radius request succeeded and -1 otherwise.
|
|
*/
|
|
int radius_load_callee_avps(struct sip_msg* _m, char* _callee, char* _s2)
|
|
{
|
|
str user;
|
|
VALUE_PAIR *send, *received;
|
|
uint32_t service;
|
|
static char msg[4096];
|
|
int extra_cnt, offset, i, res;
|
|
|
|
send = received = 0;
|
|
|
|
if ((_callee == NULL) ||
|
|
(fixup_get_svalue(_m, (gparam_p)_callee, &user) != 0)) {
|
|
LM_ERR("invalid callee parameter");
|
|
return -1;
|
|
}
|
|
|
|
if (!rc_avpair_add(rh, &send, callee_attrs[SA_USER_NAME].v,
|
|
user.s, user.len, 0)) {
|
|
LM_ERR("in adding SA_USER_NAME\n");
|
|
return -1;
|
|
}
|
|
|
|
service = callee_vals[EV_SIP_CALLEE_AVPS].v;
|
|
if (!rc_avpair_add(rh, &send, callee_attrs[SA_SERVICE_TYPE].v,
|
|
&service, -1, 0)) {
|
|
LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
|
|
goto error;
|
|
}
|
|
|
|
/* Add extra attributes */
|
|
extra_cnt = extra2strar(callee_extra, _m, val_arr);
|
|
if (extra_cnt == -1) {
|
|
LM_ERR("in getting values of callee extra attributes\n");
|
|
goto error;
|
|
}
|
|
offset = SA_STATIC_MAX;
|
|
for (i = 0; i < extra_cnt; i++) {
|
|
if (val_arr[i].len == -1) {
|
|
/* Add integer attribute */
|
|
ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
|
|
&(val_arr[i].s), val_arr[i].len );
|
|
} else {
|
|
/* Add string attribute */
|
|
ADD_EXTRA_AVPAIR(callee_attrs, offset+i,
|
|
val_arr[i].s, val_arr[i].len );
|
|
}
|
|
}
|
|
|
|
res = rc_auth(rh, 0, send, &received, msg);
|
|
|
|
if (res == OK_RC) {
|
|
LM_DBG("Radius Load Callee Success\n");
|
|
rc_avpair_free(send);
|
|
if (common_response) {
|
|
generate_avps_rad(received);
|
|
} else {
|
|
generate_avps(callee_attrs, received);
|
|
}
|
|
rc_avpair_free(received);
|
|
return 1;
|
|
} else if(res == BADRESP_RC){
|
|
LM_ERR("Authz radius - Load Callee - BAD RESPONSE \n");
|
|
} else if(res == ERROR_RC){
|
|
LM_ERR("Authz radius - Load Callee - ERROR \n");
|
|
} else if(res == TIMEOUT_RC){
|
|
LM_ERR("Authz radius - Load Callee - TIMEOUT \n");
|
|
} else if(res == REJECT_RC){
|
|
LM_ERR("Authz radius - Load Callee - REJECTED \n");
|
|
} else {
|
|
LM_ERR("Authz radius - Load Callee - Unkown response \n");
|
|
}
|
|
rc_avpair_free(send);
|
|
|
|
if (common_response){
|
|
generate_avps_rad(received);
|
|
}
|
|
|
|
rc_avpair_free(received);
|
|
return -1;
|
|
|
|
|
|
error:
|
|
rc_avpair_free(send);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if a user belongs to a group. User-Name is given in
|
|
* first string argment that may contain pseudo variables. SIP-Group is
|
|
* given in second string variable that may not contain pseudo variables.
|
|
* Service-Type is Group-Check.
|
|
*/
|
|
int radius_is_user_in(struct sip_msg* _m, char* _user, char* _group)
|
|
{
|
|
str user, *group;
|
|
VALUE_PAIR *send, *received;
|
|
uint32_t service;
|
|
static char msg[4096];
|
|
int extra_cnt, offset, i, res;
|
|
|
|
send = received = 0;
|
|
|
|
if ((_user == NULL) ||
|
|
(fixup_get_svalue(_m, (gparam_p)_user, &user) != 0)) {
|
|
LM_ERR("invalid user parameter");
|
|
return -1;
|
|
}
|
|
|
|
if (!rc_avpair_add(rh, &send, group_attrs[SA_USER_NAME].v,
|
|
user.s, user.len, 0)) {
|
|
LM_ERR("in adding SA_USER_NAME\n");
|
|
return -1;
|
|
}
|
|
|
|
group = (str*)_group;
|
|
if ((group == NULL) || (group->len == 0)) {
|
|
LM_ERR("invalid group parameter");
|
|
goto error;
|
|
}
|
|
if (!rc_avpair_add(rh, &send, group_attrs[SA_SIP_GROUP].v,
|
|
group->s, group->len, 0)) {
|
|
LM_ERR("in adding SA_SIP_GROUP\n");
|
|
goto error;
|
|
}
|
|
|
|
service = group_vals[GV_GROUP_CHECK].v;
|
|
if (!rc_avpair_add(rh, &send, group_attrs[SA_SERVICE_TYPE].v,
|
|
&service, -1, 0)) {
|
|
LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
|
|
goto error;
|
|
}
|
|
|
|
/* Add extra attributes */
|
|
extra_cnt = extra2strar(group_extra, _m, val_arr);
|
|
if (extra_cnt == -1) {
|
|
LM_ERR("in getting values of group extra attributes\n");
|
|
goto error;
|
|
}
|
|
offset = SA_STATIC_MAX;
|
|
for (i = 0; i < extra_cnt; i++) {
|
|
if (val_arr[i].len == -1) {
|
|
/* Add integer attribute */
|
|
ADD_EXTRA_AVPAIR(group_attrs, offset+i,
|
|
&(val_arr[i].s), val_arr[i].len );
|
|
} else {
|
|
/* Add string attribute */
|
|
ADD_EXTRA_AVPAIR(group_attrs, offset+i,
|
|
val_arr[i].s, val_arr[i].len );
|
|
}
|
|
}
|
|
|
|
res = rc_auth(rh, 0, send, &received, msg);
|
|
|
|
if (res == OK_RC) {
|
|
LM_DBG("Authz radius - success\n");
|
|
rc_avpair_free(send);
|
|
generate_avps(group_attrs, received);
|
|
rc_avpair_free(received);
|
|
return 1;
|
|
} else if(res == BADRESP_RC){
|
|
LM_ERR("Authz radius - BAD RESPONSE \n");
|
|
} else if(res == ERROR_RC){
|
|
LM_ERR("Authz radius - ERROR \n");
|
|
} else if(res == TIMEOUT_RC){
|
|
LM_ERR("Authz radius - TIMEOUT \n");
|
|
} else if(res == REJECT_RC){
|
|
LM_ERR("Authz radius - REJECTED \n");
|
|
} else{
|
|
LM_ERR("Authz radius - Unkown Response \n");
|
|
}
|
|
|
|
rc_avpair_free(send);
|
|
rc_avpair_free(received);
|
|
return -1;
|
|
|
|
error:
|
|
rc_avpair_free(send);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Check from Radius if URI, whose user and host parts are given as
|
|
* arguments, exists. If so, loads AVPs based on reply items returned
|
|
* from Radius. If use_sip_uri_host module parameter has non-zero value,
|
|
* user is send in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
|
|
* attribute. If is has zero value, user@host is send in SA_USER_NAME
|
|
* attribute.
|
|
*/
|
|
int radius_does_uri_user_host_exist(struct sip_msg* _m, str user, str host)
|
|
{
|
|
char* at, *user_host;
|
|
VALUE_PAIR *send, *received;
|
|
uint32_t service;
|
|
static char msg[4096];
|
|
int extra_cnt, offset, i, res;
|
|
|
|
send = received = 0;
|
|
user_host = 0;
|
|
|
|
if (!use_sip_uri_host) {
|
|
|
|
/* Send user@host in SA_USER_NAME attr */
|
|
user_host = (char*)pkg_malloc(user.len + host.len + 2);
|
|
if (!user_host) {
|
|
LM_ERR("no more pkg memory\n");
|
|
return -1;
|
|
}
|
|
at = user_host;
|
|
memcpy(at, user.s, user.len);
|
|
at += user.len;
|
|
*at = '@';
|
|
at++;
|
|
memcpy(at , host.s, host.len);
|
|
at += host.len;
|
|
*at = '\0';
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user_host,
|
|
-1, 0)) {
|
|
LM_ERR("in adding SA_USER_NAME\n");
|
|
pkg_free(user_host);
|
|
return -1;
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Send user in SA_USER_NAME attribute and host in SA_SIP_URI_HOST
|
|
attribute */
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
|
|
user.s, user.len, 0)) {
|
|
LM_ERR("adding User-Name failed\n");
|
|
return -1;
|
|
}
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_SIP_URI_HOST].v,
|
|
host.s, host.len, 0)) {
|
|
LM_ERR("adding SIP-URI-Host failed\n");
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
service = uri_vals[UV_CALL_CHECK].v;
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
|
|
&service, -1, 0)) {
|
|
LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
|
|
goto error;
|
|
}
|
|
|
|
/* Add extra attributes */
|
|
extra_cnt = extra2strar(uri_extra, _m, val_arr);
|
|
if (extra_cnt == -1) {
|
|
LM_ERR("in getting values of group extra attributes\n");
|
|
goto error;
|
|
}
|
|
offset = SA_STATIC_MAX;
|
|
for (i = 0; i < extra_cnt; i++) {
|
|
if (val_arr[i].len == -1) {
|
|
/* Add integer attribute */
|
|
ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
|
|
&(val_arr[i].s), val_arr[i].len );
|
|
} else {
|
|
/* Add string attribute */
|
|
ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
|
|
val_arr[i].s, val_arr[i].len );
|
|
}
|
|
}
|
|
|
|
if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) {
|
|
LM_DBG("success\n");
|
|
if (user_host) pkg_free(user_host);
|
|
rc_avpair_free(send);
|
|
generate_avps(uri_attrs, received);
|
|
rc_avpair_free(received);
|
|
return 1;
|
|
} else {
|
|
if (user_host) pkg_free(user_host);
|
|
rc_avpair_free(send);
|
|
rc_avpair_free(received);
|
|
#ifdef REJECT_RC
|
|
if (res == REJECT_RC) {
|
|
LM_DBG("rejected\n");
|
|
return -1;
|
|
} else {
|
|
LM_ERR("failure\n");
|
|
return -2;
|
|
}
|
|
#else
|
|
LM_DBG("failure\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
error:
|
|
rc_avpair_free(send);
|
|
if (user_host) pkg_free(user_host);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if Request URI belongs to a local user.
|
|
* If so, loads AVPs based on reply items returned from Radius.
|
|
*/
|
|
int radius_does_uri_exist_0(struct sip_msg* _m, char* _s1, char* _s2)
|
|
{
|
|
|
|
if (parse_sip_msg_uri(_m) < 0) {
|
|
LM_ERR("parsing Request-URI failed\n");
|
|
return -1;
|
|
}
|
|
|
|
return radius_does_uri_user_host_exist(_m, _m->parsed_uri.user,
|
|
_m->parsed_uri.host);
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if URI given in pvar argument belongs to a local user.
|
|
* If so, loads AVPs based on reply items returned from Radius.
|
|
*/
|
|
int radius_does_uri_exist_1(struct sip_msg* _m, char* _sp, char* _s2)
|
|
{
|
|
pv_spec_t *sp;
|
|
pv_value_t pv_val;
|
|
struct sip_uri parsed_uri;
|
|
|
|
sp = (pv_spec_t *)_sp;
|
|
|
|
if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
|
|
if (pv_val.flags & PV_VAL_STR) {
|
|
if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
|
|
LM_ERR("pvar argument is empty\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
LM_ERR("pvar value is not string\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
LM_ERR("cannot get pvar value\n");
|
|
return -1;
|
|
}
|
|
|
|
if (parse_uri(pv_val.rs.s, pv_val.rs.len, &parsed_uri) < 0) {
|
|
LM_ERR("parsing of URI in pvar failed\n");
|
|
return -1;
|
|
}
|
|
|
|
return radius_does_uri_user_host_exist(_m, parsed_uri.user,
|
|
parsed_uri.host);
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if URI user given as argument belongs to a local user.
|
|
* If so, loads AVPs based on reply items returned from Radius.
|
|
*/
|
|
int radius_does_uri_user_exist(struct sip_msg* _m, str user)
|
|
{
|
|
static char msg[4096];
|
|
VALUE_PAIR *send, *received;
|
|
uint32_t service;
|
|
int res, extra_cnt, offset, i;
|
|
|
|
send = received = 0;
|
|
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v,
|
|
user.s, user.len, 0)) {
|
|
LM_ERR("in adding SA_USER_NAME\n");
|
|
return -1;
|
|
}
|
|
|
|
service = uri_vals[UV_CALL_CHECK].v;
|
|
if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v,
|
|
&service, -1, 0)) {
|
|
LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service);
|
|
goto error;
|
|
}
|
|
|
|
/* Add extra attributes */
|
|
extra_cnt = extra2strar(uri_extra, _m, val_arr);
|
|
if (extra_cnt == -1) {
|
|
LM_ERR("in getting values of group extra attributes\n");
|
|
goto error;
|
|
}
|
|
offset = SA_STATIC_MAX;
|
|
for (i = 0; i < extra_cnt; i++) {
|
|
if (val_arr[i].len == -1) {
|
|
/* Add integer attribute */
|
|
ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
|
|
&(val_arr[i].s), val_arr[i].len );
|
|
} else {
|
|
/* Add string attribute */
|
|
ADD_EXTRA_AVPAIR(uri_attrs, offset+i,
|
|
val_arr[i].s, val_arr[i].len );
|
|
}
|
|
}
|
|
|
|
res = rc_auth(rh, 0, send, &received, msg);
|
|
|
|
if (res == OK_RC) {
|
|
LM_DBG("Radius Success\n");
|
|
rc_avpair_free(send);
|
|
generate_avps(uri_attrs, received);
|
|
rc_avpair_free(received);
|
|
return 1;
|
|
} else if(res == BADRESP_RC){
|
|
LM_ERR("Authz radius - BAD RESPONSE \n");
|
|
} else if(res == ERROR_RC){
|
|
LM_ERR("Authz radius - ERROR \n");
|
|
} else if(res == TIMEOUT_RC){
|
|
LM_ERR("Authz radius - TIMEOUT \n");
|
|
} else if(res == REJECT_RC){
|
|
LM_ERR("Authz radius - REJECTED \n");
|
|
} else {
|
|
LM_ERR("Authz radius - Unkown response \n");
|
|
}
|
|
|
|
rc_avpair_free(send);
|
|
rc_avpair_free(received);
|
|
|
|
return -1;
|
|
error:
|
|
rc_avpair_free(send);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if Request URI user belongs to a local user.
|
|
* If so, loads AVPs based on reply items returned from Radius.
|
|
*/
|
|
int radius_does_uri_user_exist_0(struct sip_msg* _m, char* _s1, char* _s2)
|
|
{
|
|
|
|
if (parse_sip_msg_uri(_m) < 0) {
|
|
LM_ERR("parsing Request-URI failed\n");
|
|
return -1;
|
|
}
|
|
|
|
return radius_does_uri_user_exist(_m, _m->parsed_uri.user);
|
|
}
|
|
|
|
|
|
/*
|
|
* Check from Radius if URI user given in pvar argument belongs
|
|
* to a local user. If so, loads AVPs based on reply items returned
|
|
* from Radius.
|
|
*/
|
|
int radius_does_uri_user_exist_1(struct sip_msg* _m, char* _sp, char* _s2)
|
|
{
|
|
pv_spec_t *sp;
|
|
pv_value_t pv_val;
|
|
|
|
sp = (pv_spec_t *)_sp;
|
|
|
|
if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
|
|
if (pv_val.flags & PV_VAL_STR) {
|
|
if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
|
|
LM_ERR("pvar argument is empty\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
LM_ERR("pvar value is not string\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
LM_ERR("cannot get pvar value\n");
|
|
return -1;
|
|
}
|
|
|
|
return radius_does_uri_user_exist(_m, pv_val.rs);
|
|
}
|