Пример #1
0
/* 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;
}
Пример #2
0
/*
 * Generate AVPs from the database result
 */
static int generate_avps(VALUE_PAIR* received)
{
	int_str name, val;
	unsigned short flags;
	VALUE_PAIR *vp;

	LM_DBG("getting AVPs from RADIUS Reply\n");
	vp = received;
	if ( ! ar_radius_avps_mode )
		vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0);
	for( ; vp; vp=((ar_radius_avps_mode)?vp->next:rc_avpair_get(vp->next,attrs[A_SIP_AVP].v,0)) ) {
		flags = 0;
		if (!extract_avp( vp, &flags, &name, &val)){
			LM_ERR("error while extracting AVP '%.*s'\n",(int)strlen(vp->name),vp->name);
			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 0;
}
Пример #3
0
int send_auth_func(struct sip_msg* msg, str* s1, str* s2) {

	int i, res;
	int index1 = -1, index2 = -1;
	map_list *mp;
	pv_value_t pvt;
	char mess[1024];

	VALUE_PAIR *send = NULL, *recv = NULL, *vp = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s1->len &&
				!strncmp(sets[i]->set_name.s, s1->s, s1->len))
				index1 = i;
		if (sets[i]->set_name.len == s2->len &&
				!strncmp(sets[i]->set_name.s, s2->s, s2->len))
				index2 = i;
	}

	if (index1 == -1) {
		LM_ERR("the first set was not found\n");
		return -1;
	}

	if (index2 == -1) {
		LM_ERR("the second set was not found\n");
		return -1;
	}

	if (make_send_message(msg, index1, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	res = rc_auth(rh, SIP_PORT, send, &recv, mess);
	if (res!=OK_RC && res!=BADRESP_RC) {
		LM_ERR("radius authentication message failed with %s\n",
			(res==TIMEOUT_RC)?"TIMEOUT":"ERROR");
	}else{
		LM_DBG("radius authentication message sent\n");
	}

	for ( mp=sets[index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=BADRESP_RC)
		goto error;


	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);

	return (res==OK_RC)?1:-2;
error:
	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);
	return -1;
}
Пример #4
0
static int load_avp_user(struct sip_msg* msg, str* prefix, load_avp_param_t type)
{
	static char rad_msg[4096];
	str user_domain, buffer;
	str* user, *domain, *uri;
	struct hdr_field* h;
	dig_cred_t* cred = 0;
	int_str name, val;
	unsigned short flags;

	VALUE_PAIR* send, *received, *vp;
	UINT4 service;
	struct sip_uri puri;
	
	send = received = 0;
	user_domain.s = 0;

	switch(type) {
	case LOAD_CALLER:
		     /* Use From header field */
		if (parse_from_header(msg) < 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing From header field\n");
			return -1;
		}

		uri = &get_from(msg)->uri;
		if (parse_uri(uri->s, uri->len, &puri) == -1) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing From URI\n");
			return -1;
		}

		user = &puri.user;
		domain = &puri.host;
		service = vals[V_SIP_CALLER_AVPS].v;
		break;

	case LOAD_CALLEE:
		     /* Use the Request-URI */
		if (parse_sip_msg_uri(msg) < 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Error while "
				"parsing Request-URI\n");
			return -1;
		}

		if (msg->parsed_uri.user.len == 0) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: Request-URI user "
				"is missing\n");
			return -1;
		}
		
		user = &msg->parsed_uri.user; 
		domain = &msg->parsed_uri.host;
		service = vals[V_SIP_CALLEE_AVPS].v;
		break;

	case LOAD_DIGEST:
		     /* Use digest credentials */
		get_authorized_cred(msg->proxy_auth, &h);
		if (!h) {
			LOG(L_ERR, "ERROR:avp_radius:load_avp_user: No authoried "
				"credentials\n");
			return -1;
		}

		cred = &((auth_body_t*)(h->parsed))->digest;
		user = &cred->username.user;
		domain = &cred->realm;
		service = vals[V_SIP_CALLER_AVPS].v;
		break;

	default:
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Unknown user type\n");
		return -1;
		
	}

	user_domain.len = user->len + 1 + domain->len;
	user_domain.s = (char*)pkg_malloc(user_domain.len);
	if (!user_domain.s) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: No pkg memory left\n");
		return -1;
	}

	memcpy(user_domain.s, user->s, user->len);
	user_domain.s[user->len] = '@';
	memcpy(user_domain.s + user->len + 1, domain->s, domain->len);

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
			user_domain.s, user_domain.len, 0)) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Error adding "
			"PW_USER_NAME\n");
		goto error;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Error adding "
			"PW_SERVICE_TYPE\n");
		goto error;
	}

	if (rc_auth(rh, 0, send, &received, rad_msg) == OK_RC) {
		DBG("DEBUG:avp_radius:avp_load_user: rc_auth Success\n");
		rc_avpair_free(send);
		pkg_free(user_domain.s);

		vp = received;
		for( ; (vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0)) ; vp=vp->next) {
			flags = 0;
			if (extract_avp( vp, &flags, &name, &val)!=0 )
				continue;

			/* append prefix only if AVP has name */
			if (flags&AVP_NAME_STR) {
				buffer.len = prefix->len + name.s->len;
				buffer.s = (char*)pkg_malloc(buffer.len);
				if (!buffer.s) {
					LOG(L_ERR, "ERROR:avp_radius:avp_load_user: "******"No pkg memory left\n");
					return -1;
				}
				memcpy(buffer.s, prefix->s, prefix->len);
				memcpy(buffer.s + prefix->len, name.s->s, name.s->len);
				name.s = &buffer;
			} else {
				buffer.s = 0;
			}

			if (add_avp( flags, name, val) < 0) {
				LOG(L_ERR, "ERROR:avp_radius:avp_load_user: Unable to create "
					"a new AVP\n");
			} else {
				DBG("DEBUG:avp_radius:generate_avps: "
					"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 );
			}

			if (buffer.s) 
				pkg_free(buffer.s);
		}

		rc_avpair_free(received);
		return 1;
	} else {
		LOG(L_ERR,"ERROR:avp_radius:avp_load_user: rc_auth failed\n");
	}

error:
	if (send) rc_avpair_free(send);
	if (received) rc_avpair_free(received);
	if (user_domain.s) pkg_free(user_domain.s);
	return -1;
}
Пример #5
0
/*
	Radius implementation for the send_message callback
 */
int rad_send_message(aaa_conn* rh, aaa_message* request, aaa_message** reply) {
	char msg[4096];
	VALUE_PAIR *vp;
 	DICT_ATTR *attr;
	int result;

	if (!rh) {
		LM_ERR("invalid aaa connection argument\n");
		return -1;
	}

	if (!request) {
		LM_ERR("invalid argument\n");
		return -1;
	}

	if (request->type == AAA_AUTH) {

		*reply = (aaa_message*) pkg_malloc (sizeof(aaa_message));

		if (!(*reply)) {
			LM_ERR("no pkg memory left \n");
			return -1;
		}

		(*reply)->type = AAA_RECV;
		(*reply)->avpair = NULL;
		(*reply)->last_found = NULL;

		result = rc_auth(rh, SIP_PORT, (VALUE_PAIR*) request->avpair,
						(VALUE_PAIR**)(void*)&(*reply)->avpair, msg);

		if (result == OK_RC) {
			attr = rc_dict_findattr(rh, "SIP-AVP");
			if (attr) {
				vp = (*reply)->avpair;
				for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
					if (extract_avp(vp)) {
						LM_ERR("extract_avp failed\n");
						return -1;
					}
				return 0;
			} else {
				LM_ERR("SIP-AVP was not found in the radius dictionary\n");
				return -1;
			}
		} else if (result == REJECT_RC) {
			LM_DBG("rc_auth function succeded with result REJECT_RC\n");
			return result;
		} else {
			LM_ERR("rc_auth function failed\n");
			return -1;
		}
	}

	if (request->type == AAA_ACCT) {
			return rc_acct(rh, SIP_PORT, (VALUE_PAIR*) request->avpair);
	}

	LM_ERR("send message failure\n");
	return -1;
}
Пример #6
0
/* TODO
 * when timeout mechanism will be available
 * rc_auth_function shall be called to try another
 * destination if the current one has timed out
 * */
int resume_send_auth(int fd, struct sip_msg *msg, void *param)
{
	int res;
	map_list *mp;
	pv_value_t pvt;
	struct rad_ctx *rctx;

	VALUE_PAIR *recv = NULL, *vp = NULL;

	rctx = (struct rad_ctx *)param;
	if (rctx == NULL) {
		LM_ERR("no context given\n");
		return -1;
	}

	res = rc_auth_resume(&rctx->ctx, &recv);

	if (res == OK_RC || res == REJECT_RC) {
		async_status = ASYNC_DONE;
	} else if (res == READBLOCK_RC) {
		async_status  = ASYNC_CONTINUE;
		return 1;
	} else {
		LM_ERR("radius authentication message failed with %s\n",
							((res==BADRESP_RC)?"BAD REPLY":"ERROR"));
		goto error;
	}

	for ( mp=sets[rctx->index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=REJECT_RC)
		goto error;


	if (rctx->send) rc_avpair_free(rctx->send);
	if (recv) rc_avpair_free(recv);

	pkg_free(rctx);

	return (res==OK_RC)?1:-2;
error:
	pkg_free(rctx);
	if (rctx->send) rc_avpair_free(rctx->send);
	if (recv) rc_avpair_free(recv);
	return -1;

}