Beispiel #1
0
/*
 * Check if username in specified header field is in a table
 */
int is_user_in(struct sip_msg* _msg, char* _hf, char* _grp)
{
	db_key_t keys[3];
	db_val_t vals[3];
	db_key_t col[1];
	db_res_t* res;
	str uri;
	long hf_type;
	struct sip_uri puri;
	struct hdr_field* h;
	struct auth_body* c = 0; /* Makes gcc happy */
	group_check_p gcp=NULL;
	xl_value_t value;
	
	keys[0] = user_column.s;
	keys[1] = group_column.s;
	keys[2] = domain_column.s;
	col[0] = group_column.s;
	
	gcp = (group_check_p)_hf;
	hf_type = (long)gcp->id;

	uri.s = 0;
	uri.len = 0;

	switch(hf_type) {
	case 1: /* Request-URI */
		if (get_request_uri(_msg, &uri) < 0) {
			LOG(L_ERR, "is_user_in(): Error while obtaining username from Request-URI\n");
			return -1;
		}
		break;

	case 2: /* To */
		if (get_to_uri(_msg, &uri) < 0) {
			LOG(L_ERR, "is_user_in(): Error while extracting To username\n");
			return -2;
		}
		break;

	case 3: /* From */
		if (get_from_uri(_msg, &uri) < 0) {
			LOG(L_ERR, "is_user_in(): Error while extracting From username\n");
			return -3;
		}
		break;

	case 4: /* Credentials */
		get_authorized_cred(_msg->authorization, &h);
		if (!h) {
			get_authorized_cred(_msg->proxy_auth, &h);
			if (!h) {
				LOG(L_ERR, "is_user_in(): No authorized credentials found (error in scripts)\n");
				return -1;
			}
		}
	
		c = (auth_body_t*)(h->parsed);
		break;
	case 5: /* AVP spec */
		if(xl_get_spec_value(_msg, &gcp->sp, &value)!=0 
				|| value.flags&XL_VAL_NULL || value.rs.len<=0)
		{
			LOG(L_ERR,
				"is_user_in(): no AVP found (error in scripts)\n");
			return -1;
		}
		uri.s = value.rs.s;
		uri.len = value.rs.len;
		break;
	}

	if (hf_type != 4) {
		if (parse_uri(uri.s, uri.len, &puri) < 0) {
			LOG(L_ERR, "is_user_in(): Error while parsing URI\n");
			return -5;
		}

		VAL_STR(vals) = puri.user;
		VAL_STR(vals + 2) = puri.host;
	} else {
		VAL_STR(vals) = c->digest.username.user;
		VAL_STR(vals + 2) = *(GET_REALM(&c->digest));
	}
	
	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0;

	VAL_STR(vals + 1) = *((str*)_grp);
	
	if (group_dbf.use_table(db_handle, table.s) < 0) {
		LOG(L_ERR, "is_user_in(): Error in use_table\n");
		return -5;
	}

	if (group_dbf.query(db_handle, keys, 0, vals, col, (use_domain) ? (3): (2),
				1, 0, &res) < 0) {
		LOG(L_ERR, "is_user_in(): Error while querying database\n");
		return -5;
	}
	
	if (RES_ROW_N(res) == 0) {
		DBG("is_user_in(): User is not in group '%.*s'\n", 
		    ((str*)_grp)->len, ZSW(((str*)_grp)->s));
		group_dbf.free_result(db_handle, res);
		return -6;
	} else {
		DBG("is_user_in(): User is in group '%.*s'\n", 
		    ((str*)_grp)->len, ZSW(((str*)_grp)->s));
		group_dbf.free_result(db_handle, res);
		return 1;
	}
}
Beispiel #2
0
/* it checks if a user is member of a group */
int diameter_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain, uri;
	dig_cred_t* cred = 0;
	int hf_type;
	struct hdr_field* h;
	struct sip_uri puri;
	AAAMessage *req;
	AAA_AVP *avp; 
	int ret;
	unsigned int tmp;

	grp = (str*)_group; /* via fixup */

	hf_type = (int)(long)_hf;

	uri.s = 0;
	uri.len = 0;

	/* extract the uri according with the _hf parameter */
	switch(hf_type) 
	{
		case 1: /* Request-URI */
			uri = *(GET_RURI(_m));
		break;

		case 2: /* To */
			if (get_to_uri(_m, &uri) < 0) 
			{
				LM_ERR("failed to extract To\n");
				return -2;
			}
			break;

		case 3: /* From */
			if (get_from_uri(_m, &uri) < 0) 
			{
				LM_ERR("failed to extract From URI\n");
				return -3;
			}
			break;

		case 4: /* Credentials */
			get_authorized_cred(_m->authorization, &h);
			if (!h) 	
			{
				get_authorized_cred(_m->proxy_auth, &h);
				if (!h) 
				{
					LM_ERR("no authorized credentials found "
							"(error in scripts)\n");
					return -4;
				}
			}
			cred = &((auth_body_t*)(h->parsed))->digest;
			break;
	}

	if (hf_type != 4) 
	{
		if (parse_uri(uri.s, uri.len, &puri) < 0) 
		{
			LM_ERR("failed to parse URI\n");
			return -5;
		}
		user = puri.user;
		domain = puri.host;
	} 
	else
	{
		user = cred->username.user;
		domain = cred->realm;
	}
	
	/* user@domain mode */
	if (use_domain)
	{
		user_name.s = 0;
		user_name.len = user.len + domain.len;
		if(user_name.len>0)
		{
			user_name.len++;
			user_name.s = (char*)pkg_malloc(user_name.len);
			if (!user_name.s) 
			{
				LM_ERR("no pkg memory left\n");
				return -6;
			}
		
			memcpy(user_name.s, user.s, user.len);
			if(user.len>0)
			{
				user_name.s[user.len] = '@';
				memcpy(user_name.s + user.len + 1, domain.s, domain.len);
			}
			else
				memcpy(user_name.s, domain.s, domain.len);
		}
	} 
	else 
		user_name = user;
	
	
	if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL)
	{
		LM_ERR("can't create new AAA message!\n");
		return -1;
	}
	
	/* Username AVP */
	if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s,
				user_name.len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	/* Usergroup AVP */
	if( (avp=AAACreateAVP(AVP_User_Group, 0, 0, grp->s,
				grp->len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	/* SIP_MSGID AVP */
	LM_DBG("******* m_id=%d\n", _m->id);
	tmp = _m->id;
	if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp), 
				sizeof(tmp), AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	
	/* ServiceType AVP */
	if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_GROUP_CHECK, 
				SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}
	

	/* Destination-Realm AVP */
	uri = *(GET_RURI(_m));
	parse_uri(uri.s, uri.len, &puri);
	if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s,
						puri.host.len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}
	
#ifdef DEBUG
	AAAPrintMessage(req);
#endif

	/* build a AAA message buffer */
	if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS)
	{
		LM_ERR("message buffer not created\n");
		goto error;
	}

	if(sockfd==AAA_NO_CONNECTION)
	{
		sockfd = init_mytcp(diameter_client_host, diameter_client_port);
		if(sockfd==AAA_NO_CONNECTION)
		{
			LM_ERR("failed to reconnect to Diameter client\n");
			goto error;
		}
	}

	ret =tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, _m->id);

	if(ret == AAA_CONN_CLOSED)
	{
		LM_NOTICE("connection to Diameter client closed."
				"It will be reopened by the next request\n");
		close(sockfd);
		sockfd = AAA_NO_CONNECTION;
		goto error;
	}
	if(ret != AAA_USER_IN_GROUP)
	{
		LM_ERR("message sending to the DIAMETER backend authorization server"
				"failed or user is not in group\n");
		goto error;
	}
	
	AAAFreeMessage(&req);
	return 1;

error1:
	AAAFreeAVP(&avp);
error:
	AAAFreeMessage(&req);
	return -1;

}
Beispiel #3
0
/*
 * Check from Radius if a user belongs to a group. User-Name is digest
 * username or digest username@realm, SIP-Group is group, and Service-Type
 * is Group-Check.  SIP-Group is SER specific attribute and Group-Check is
 * SER specific service type value.
 */
int radius_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain, uri;
	dig_cred_t* cred = 0;
	int hf_type;
	UINT4 service;
	VALUE_PAIR *send, *received;
	static char msg[4096];
	struct hdr_field* h;
	struct sip_uri puri;

	grp = (str*)_group; /* via fixup */
	send = received = 0;

	hf_type = (int)(long)_hf;

	uri.s = 0;
	uri.len = 0;

	switch(hf_type) {
	case 1: /* Request-URI */
		if (get_request_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting Request-URI\n");
			return -1;
		}
		break;

	case 2: /* To */
		if (get_to_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting To\n");
			return -2;
		}
		break;

	case 3: /* From */
		if (get_from_uri(_m, &uri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while extracting From\n");
			return -3;
		}
		break;

	case 4: /* Credentials */
		get_authorized_cred(_m->authorization, &h);
		if (!h) {
			get_authorized_cred(_m->proxy_auth, &h);
			if (!h) {
				LOG(L_ERR, "radius_is_user_in(): No authorized credentials found (error in scripts)\n");
				return -4;
			}
		}
		cred = &((auth_body_t*)(h->parsed))->digest;
		break;
	}

	if (hf_type != 4) {
		if (parse_uri(uri.s, uri.len, &puri) < 0) {
			LOG(L_ERR, "radius_is_user_in(): Error while parsing URI\n");
			return -5;
		}
		user = puri.user;
		domain = puri.host;
	} else {
		user = cred->username.user;
		domain = *GET_REALM(cred);
	}
		

	if (use_domain) {
		user_name.len = user.len + domain.len + 1;
		user_name.s = (char*)pkg_malloc(user_name.len);
		if (!user_name.s) {
			LOG(L_ERR, "radius_is_user_in(): No memory left\n");
			return -6;
		}
		
		memcpy(user_name.s, user.s, user.len);
		user_name.s[user.len] = '@';
		memcpy(user_name.s + user.len + 1, domain.s, domain.len);
	} else {
		user_name = user;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding User-Name attribute\n");
		rc_avpair_free(send);
		if (use_domain) pkg_free(user_name.s);
		return -7;
	}

	if (use_domain) pkg_free(user_name.s);

	if (!rc_avpair_add(rh, &send, attrs[A_SIP_GROUP].v, grp->s, grp->len, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding Sip-Group attribute\n");
	 	return -8;  	
	}

	service = vals[V_GROUP_CHECK].v;
	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LOG(L_ERR, "radius_is_user_in(): Error adding Service-Type attribute\n");
		rc_avpair_free(send);
	 	return -9;  	
	}

	if (rc_auth(rh, 0, send, &received, msg) == OK_RC) {
		DBG("radius_is_user_in(): Success\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return 1;
	} else {
		DBG("radius_is_user_in(): Failure\n");
		rc_avpair_free(send);
		rc_avpair_free(received);
		return -11;
	}
}