Exemple #1
0
/*
 * Send Radius request to verify source.
 */
int verify_source(struct sip_msg* _msg, char* s1, char* s2)
{
    aaa_message *send = NULL, *received = NULL;
	struct hdr_field *hf;
    uint32_t service;

    /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
    if (parse_sip_msg_uri(_msg) < 0) {
        LM_ERR("error while parsing Request-URI\n");
		return -1;
    }

	if ((send = proto.create_aaa_message(conn, AAA_AUTH)) == NULL) {
		LM_ERR("failed to create new aaa message for auth\n");
		return -1;
	}

    if (proto.avp_add(conn, send, &attrs[A_USER_NAME],
		       _msg->parsed_uri.host.s,
		       _msg->parsed_uri.host.len, 0)) {
		LM_ERR("error adding PW_USER_NAME\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_URI_USER],
		       _msg->parsed_uri.user.s,
		       _msg->parsed_uri.user.len, 0)) {
		LM_ERR("error adding PW_SIP_URI_USER\n");
		goto err;
    }

    /* Add From Tag */
    if (parse_from_header(_msg) < 0) {
		LM_ERR("error while parsing From header field\n");
		goto err;
    }

    if (_msg->from == NULL || get_from(_msg) == NULL ||
				get_from(_msg)->tag_value.s == NULL ||
				get_from(_msg)->tag_value.len <= 0) {
		LM_ERR("error while accessing From header tag\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_FROM_TAG],
		       get_from(_msg)->tag_value.s,
		       get_from(_msg)->tag_value.len, 0)) {
		LM_ERR("error adding PW_SIP_FROM_TAG\n");
		goto err;
    }

    /* Add Call-Id */
    if (parse_headers(_msg, HDR_CALLID_F, 0) == -1 ||
			_msg->callid == NULL || _msg->callid->body.s == NULL ||
			_msg->callid->body.len <= 0) {
		LM_ERR("error while accessing Call-Id\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_CALL_ID],
		       _msg->callid->body.s,
		       _msg->callid->body.len, 0)) {
		LM_ERR("error adding PW_SIP_CALL_ID\n");
		goto err;
    }

	/* Add P-Request-Hash header body */
	if (parse_headers(_msg, HDR_EOH_F, 0) < 0) {
		LM_ERR("cannot pase message!\n");
		goto err;
	}
	hf = get_header_by_static_name( _msg, "P-Request-Hash");
	if (!hf) {
		LM_ERR("no P-Request-Hash header field\n");
		goto err;
	}
    if (hf->body.s == NULL || hf->body.len <= 0) {
		LM_ERR("error while accessing P-Request-Hash body\n");
		goto err;
    }
    if (proto.avp_add(conn, send, &attrs[A_SIP_REQUEST_HASH],
		       hf->body.s, hf->body.len, 0)) {
		LM_ERR("error adding PW_SIP_REQUEST_HASH\n");
		goto err;
    }

    /* Add Service-Type */
    service = vals[V_SIP_VERIFY_SOURCE].value;
    if (proto.avp_add(conn, send, &attrs[A_SERVICE_TYPE], &service, -1, 0)) {
		LM_ERR("error adding PW_SERVICE_TYPE\n");
		goto err;
    }

    /* Send Request and generate AVPs of positive reply */
    if (!proto.send_aaa_request(conn, send, &received)) {
		LM_DBG("success\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return 1;
	}

	LM_DBG("failure\n");

err:
    if (send)
		proto.destroy_aaa_message(conn, send);
    if (received)
		proto.destroy_aaa_message(conn, received);
    return -1;
}
Exemple #2
0
static int pv_auth_check(sip_msg_t *msg, str *srealm, str *spasswd, int vflags,
		int vchecks)
{
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;
	str suser;

	if(msg->REQ_METHOD==METHOD_REGISTER)
		ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_AUTHORIZATION_T,
				&msg->first_line.u.request.method);
	else
		ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_PROXYAUTH_T,
				&msg->first_line.u.request.method);

	if(ret==AUTH_OK && (vchecks&AUTH_CHECK_ID_F)) {
		hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
		suser = ((auth_body_t*)(hdr->parsed))->digest.username.user;

		if((furi=parse_from_uri(msg))==NULL)
			return AUTH_ERROR;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(msg))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(suser.len!=uri->user.len
				|| strncmp(suser.s, uri->user.s, suser.len)!=0)
			return AUTH_USER_MISMATCH;

		if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
				return AUTH_USER_MISMATCH;
			if(auth_use_domain!=0 && (furi->host.len!=turi->host.len
						|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
				return AUTH_USER_MISMATCH;
			/* check r-uri==from for publish */
			if(msg->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(msg)<0)
					return AUTH_ERROR;
				uri = &msg->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
					return AUTH_USER_MISMATCH;
				if(auth_use_domain!=0 && (furi->host.len!=uri->host.len
							|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
					return AUTH_USER_MISMATCH;
			}
		}
		return AUTH_OK;
	}

	return ret;
}
Exemple #3
0
/*
 * Do loose routing as defined in RFC3261
 */
int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
{
	int ret;

	removed_routes = 0;
	routing_type = 0;

	if (find_first_route(_m) != 0) {
		LM_DBG("There is no Route HF\n");
		return -1;
	}
		
	if (parse_sip_msg_uri(_m)<0) {
		LM_ERR("failed to parse Request URI\n");
		return -1;
	}

	ret = is_preloaded(_m);
	if (ret < 0) {
		return -1;
	} else if (ret == 1) {
		return after_loose(_m, 1);
	} else {
#ifdef ENABLE_USER_CHECK
		if (is_myself(&_m->parsed_uri.user, &_m->parsed_uri.host,
		_m->parsed_uri.port_no)) {
#else
		if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)) {
#endif
			return after_strict(_m);
		} else {
			return after_loose(_m, 0);
		}
	}
}


int get_route_params(struct sip_msg *msg, str *val)
{
	if(msg==NULL)
		return -1;

	/* check if the hooked params belong to the same message */
	if (routed_msg_id != msg->id)
		return -1;

	val->s = routed_params.s;
	val->len = routed_params.len;

	return 0;
}


int check_route_param(struct sip_msg * msg, regex_t* re)
{
	regmatch_t pmatch;
	char bk;
	str params;

	/* check if the hooked params belong to the same message */
	if (routed_msg_id != msg->id)
		return -1;

	/* check if params are present */
	if ( !routed_params.s || !routed_params.len )
		return -1;

	/* include also the first ';' */
	for( params=routed_params ; params.s[0]!=';' ; params.s--,params.len++ );

	/* do the well-known trick to convert to null terminted */
	bk = params.s[params.len];
	params.s[params.len] = 0;
	LM_DBG("params are <%s>\n", params.s);
	if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
		params.s[params.len] = bk;
		return -1;
	} else {
		params.s[params.len] = bk;
		return 0;
	}
}
Exemple #4
0
int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, *pfrom = NULL; 
	subs_t subs;
	pres_ev_t* event= NULL;
	str* contact= NULL;
	xmlDocPtr doc= NULL;
	xmlNodePtr service_node= NULL;
	unsigned int hash_code= 0;
	event_t* parsed_event;
	param_t* ev_param= NULL;
	int init_req;
	int reply_code;
	str reply_str;

	/*** filter: 'For me or for presence server?' */

	reply_code = 400;
	reply_str = pu_400_rpl;

	memset(&subs, 0, sizeof(subs_t));

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		goto error;
	}

	/* check for Support: eventlist header */
	if(!msg->supported)
	{
		LM_DBG("no supported header found\n");
		return to_presence_code;
	}
	
	if(parse_supported(msg) < 0)
	{
		LM_ERR("failed to parse supported headers\n");
		reply_code = 500;
		reply_str = pu_500_rpl;
		goto error;
	}

	if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST))
	{
		LM_DBG("No 'Support: eventlist' header found\n");
		return to_presence_code;
	}

	/* inspecting the Event header field */
	if(msg->event && msg->event->body.len > 0)
	{
		if (!msg->event->parsed && (parse_event(msg->event) < 0))
		{
			LM_ERR("cannot parse Event header\n");
			reply_code = 500;
			reply_str = pu_500_rpl;
			goto error;
		}
		if(! ( ((event_t*)msg->event->parsed)->parsed & rls_events) )
		{
			return to_presence_code;
		}
	}
	else
	{
		goto bad_event;
	}

	/* search event in the list */
	parsed_event= (event_t*)msg->event->parsed;
	event= pres_search_event(parsed_event);
	if(event== NULL)
	{
		goto bad_event;
	}
	subs.event= event;
	
	/* extract the id if any*/
	ev_param= parsed_event->params;
	while(ev_param)
	{
		if(ev_param->name.len== 2 && strncasecmp(ev_param->name.s, "id", 2)== 0)
		{
			subs.event_id= ev_param->body;
			break;
		}
		ev_param= ev_param->next;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK)
	{
		LM_ERR("parsing 'To' header failed\n");
		goto error;
	}

	if(parse_from_uri(msg)<0)
	{
		LM_ERR("failed to parse From header\n");
		goto error;
	}

	pfrom = (struct to_body*)msg->from->parsed;
	if(pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}

	/* verify if the presentity URI is a resource list */
	if(pto->tag_value.s== NULL || pto->tag_value.len==0)
		/* if an initial Subscribe */
	{
		struct sip_uri fu = ((struct to_body*)msg->from->parsed)->parsed_uri;
		if( parse_sip_msg_uri(msg)< 0)
		{
			LM_ERR("parsing Request URI failed\n");
			goto error;
		}

		/*verify if Request URI represents a list by asking xcap server*/	
		if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
					&subs.pres_uri)< 0)
		{
			LM_ERR("while constructing uri from user and domain\n");
			reply_code = 500;
			reply_str = pu_500_rpl;
			goto error;
		}
		
		if( get_resource_list(&subs.pres_uri, fu.user, fu.host,
					&service_node, &doc) < 0)
		{
			LM_ERR("failed to get resource list document\n");
			reply_code = 500;
			reply_str = pu_500_rpl;
			goto error;
		}
		
		if(doc== NULL|| service_node==NULL)
		{
			LM_DBG("list not found - search for uri = %.*s\n",subs.pres_uri.len,
				subs.pres_uri.s);
			pkg_free(subs.pres_uri.s);
			return to_presence_code;
		}
	}
	else  /* if request inside a dialog */
	{
		if( msg->callid==NULL || msg->callid->body.s==NULL)
		{
			LM_ERR("cannot parse callid header\n");
			goto error;
		}

		/* search if a stored dialog */
		hash_code= core_hash(&msg->callid->body, &pto->tag_value, hash_size);
		lock_get(&rls_table[hash_code].lock);

		if(pres_search_shtable(rls_table,msg->callid->body,
					pto->tag_value,	pfrom->tag_value, hash_code)== NULL)
		{
			lock_release(&rls_table[hash_code].lock);
			/* reply with Call/Transaction Does Not Exist */
			LM_DBG("No dialog match found\n");
			return to_presence_code;
		}
		lock_release(&rls_table[hash_code].lock);
	}

	/* extract dialog information from message headers */
	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires, &init_req,
				server_address)< 0)
	{
		LM_ERR("bad Subscribe request\n");
		goto error;
	}

	reply_code = 500;
	reply_str = pu_500_rpl;


	if(init_req) /* if an initial subscribe */
	{
		/** reply with 200 OK*/
		if(reply_200(msg, &subs.local_contact, subs.expires, &subs.to_tag)< 0)
			goto error_free;
		hash_code= core_hash(&subs.callid, &subs.to_tag, hash_size);

		subs.local_cseq= 0;

		if(subs.expires!= 0)
		{
			subs.version= 1;
			if(pres_insert_shtable(rls_table, hash_code, &subs)< 0)
			{
				LM_ERR("while adding new subscription\n");
				goto error_free;
			}
		}
	}
	else
	{
		if(update_rlsubs(&subs, hash_code, &reply_code, &reply_str) < 0)
		{
			LM_ERR("while updating resource list subscription\n");
			goto error;
		}

		if(get_resource_list(&subs.pres_uri, subs.from_user,
					subs.from_domain, &service_node, &doc)< 0)
		{
			LM_ERR("when getting resource list\n");
			goto error;
		}
		if(doc== NULL || service_node== NULL)
		{
			LM_DBG("list not found( in-dialog request)- search for uri = %.*s\n",
					subs.pres_uri.len, subs.pres_uri.s);
			reply_code = 404;
			reply_str = pu_404_rpl;
			goto error;
		}

		/** reply with 200 OK*/
		if(reply_200(msg, &subs.local_contact, subs.expires, 0)< 0)
			goto error_free;
	}
/*** send Subscribe requests for all in the list */

	/* call sending Notify with full state */
	if(send_full_notify(&subs, service_node, subs.version,
				&subs.pres_uri,hash_code)< 0)
	{
		LM_ERR("while sending full state Notify\n");
		goto error_free;
	}

	if(resource_subscriptions(&subs, service_node)< 0)
	{
		LM_ERR("while sending Subscribe requests to resources in a list\n");
		goto error_free;
	}

	if(contact)
	{	
		if(contact->s)
			pkg_free(contact->s);
		pkg_free(contact);
	}
		
	pkg_free(subs.pres_uri.s);
	if(subs.record_route.s)
		pkg_free(subs.record_route.s);
	xmlFreeDoc(doc);
	return 1;


bad_event:
	if(reply_489(msg)< 0)
		LM_ERR("failed to send 489 reply\n");
	goto error_free;

error:
	if (rls_sigb.reply(msg, reply_code, &reply_str, 0) == -1)
	{
		LM_ERR("failed to send 400 reply\n");
		return -1;
	}


error_free:
	if(contact)
	{	
		if(contact->s)
			pkg_free(contact->s);
		pkg_free(contact);
	}
	if(subs.pres_uri.s)
		pkg_free(subs.pres_uri.s);
		
	if(subs.record_route.s)
			pkg_free(subs.record_route.s);	
	if(doc)
		xmlFreeDoc(doc);
	return -1;
}
Exemple #5
0
int auth_check(sip_msg_t *_m, str *srealm, str *stable, int iflags)
{
	int ret;
	hdr_field_t *hdr;
	sip_uri_t *uri = NULL;
	sip_uri_t *turi = NULL;
	sip_uri_t *furi = NULL;
	str suser;

	if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) {
		return AUTH_OK;
	}

	if (srealm->len<=0) {
		LM_ERR("invalid realm parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (stable->len==0) {
		LM_ERR("invalid table parameter - empty value\n");
		return AUTH_ERROR;
	}

	LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm->len, srealm->s,
			stable->len,  stable->s, iflags);

	hdr = NULL;
	if(_m->REQ_METHOD==METHOD_REGISTER)
		ret = digest_authenticate_hdr(_m, srealm, stable, HDR_AUTHORIZATION_T,
						&_m->first_line.u.request.method, &hdr);
	else
		ret = digest_authenticate_hdr(_m, srealm, stable, HDR_PROXYAUTH_T,
						&_m->first_line.u.request.method, &hdr);

	if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) {
		suser = ((auth_body_t*)(hdr->parsed))->digest.username.user;

		if((furi=parse_from_uri(_m))==NULL)
			return AUTH_ERROR;

		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			if((turi=parse_to_uri(_m))==NULL)
				return AUTH_ERROR;
			uri = turi;
		} else {
			uri = furi;
		}
		if(!((iflags&AUTH_CHECK_SKIPFWD_F)
				&& (_m->REQ_METHOD==METHOD_INVITE || _m->REQ_METHOD==METHOD_BYE
					|| _m->REQ_METHOD==METHOD_PRACK || _m->REQ_METHOD==METHOD_UPDATE
					|| _m->REQ_METHOD==METHOD_MESSAGE))) {
			if(suser.len!=uri->user.len
						|| strncmp(suser.s, uri->user.s, suser.len)!=0) {
				LM_DBG("authentication username mismatch with from/to username\n");
				return AUTH_USER_MISMATCH;
			}
		}

		if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
			/* check from==to */
			if(furi->user.len!=turi->user.len
					|| strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) {
				LM_DBG("from username mismatch with to username\n");
				return AUTH_USER_MISMATCH;
			}
			if(use_domain!=0 && (furi->host.len!=turi->host.len
					|| strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) {
				LM_DBG("from domain mismatch with to domain\n");
				return AUTH_USER_MISMATCH;
			}
			/* check r-uri==from for publish */
			if(_m->REQ_METHOD==METHOD_PUBLISH) {
				if(parse_sip_msg_uri(_m)<0)
					return AUTH_ERROR;
				uri = &_m->parsed_uri;
				if(furi->user.len!=uri->user.len
						|| strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) {
					LM_DBG("from username mismatch with r-uri username\n");
					return AUTH_USER_MISMATCH;
				}
				if(use_domain!=0 && (furi->host.len!=uri->host.len
						|| strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) {
					LM_DBG("from domain mismatch with r-uri domain\n");
					return AUTH_USER_MISMATCH;
				}
			}
		}
		return AUTH_OK;
	}

	return ret;
}
Exemple #6
0
int enum_pv_query_3(struct sip_msg* _msg, char* _sp, char* _suffix,
		    char* _service)
{
	char *user_s;
	int user_len, i, j, first;
	char name[MAX_DOMAIN_SIZE];
	char uri[MAX_URI_SIZE];
	char new_uri[MAX_URI_SIZE];
	unsigned int priority, curr_prio;
	qvalue_t q;
	char tostring[17];
	struct rdata* head;
	struct rdata* l;
	struct naptr_rdata* naptr;
	str pattern, replacement, result, new_result;
	str *suffix, *service;
	char string[17];
	pv_spec_t *sp;
	pv_value_t pv_val;

	sp = (pv_spec_t *)_sp;
	suffix = (str*)_suffix;
	service = (str*)_service;

	/*
	 *  Get R-URI user to tostring
	 */
	if (parse_sip_msg_uri(_msg) < 0) {
		LM_ERR("R-URI parsing failed\n");
		return -1;
	}

	user_s = _msg->parsed_uri.user.s;
	user_len = _msg->parsed_uri.user.len;

	memcpy(&(tostring[0]), user_s, user_len);
	tostring[user_len] = (char)0;

	/*
	 * Get E.164 number from pseudo variable
         */
	if (sp && (pv_get_spec_value(_msg, sp, &pv_val) == 0)) {
	    if (pv_val.flags & PV_VAL_STR) {
		if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
		    LM_DBG("Missing E.164 number\n");
		    return -1;
		}
	    } else {
		LM_DBG("Pseudo variable value is not string\n");
		return -1;
	}
	} else {
	    LM_DBG("Cannot get pseudo variable value\n");
	    return -1;
	}
	if (is_e164(&(pv_val.rs)) == -1) {
	    LM_ERR("pseudo variable does not contain an E164 number\n");
	    return -1;
	}

	user_s = pv_val.rs.s;
	user_len = pv_val.rs.len;

	memcpy(&(string[0]), user_s, user_len);
	string[user_len] = (char)0;

	j = 0;
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
	}

	memcpy(name + j, suffix->s, suffix->len + 1);

	head = get_record(name, T_NAPTR);

	if (head == 0) {
		LM_DBG("No NAPTR record found for %s.\n", name);
		return -1;
	}

	naptr_sort(&head);

	q = MAX_Q - 10;
	curr_prio = 0;
	first = 1;

	for (l = head; l; l = l->next) {

		if (l->type != T_NAPTR) continue; /*should never happen*/
		naptr = (struct naptr_rdata*)l->rdata;
		if (naptr == 0) {
			LM_ERR("Null rdata in DNS response\n");
			continue;
		}

		LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
		       "'%.*s', slen %u, services '%.*s', rlen %u, "
		       "regexp '%.*s'\n",
		       name, naptr->order, naptr->pref,
		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
		    naptr->services_len,
		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
		    (int)(naptr->regexp_len), ZSW(naptr->regexp));

		if (sip_match(naptr, service) == 0) continue;

		if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
				       &pattern, &replacement) < 0) {
			LM_ERR("Parsing of NAPTR regexp failed\n");
			continue;
		}
		result.s = &(uri[0]);
		result.len = MAX_URI_SIZE;
		/* Avoid making copies of pattern and replacement */
		pattern.s[pattern.len] = (char)0;
		replacement.s[replacement.len] = (char)0;
		if (reg_replace(pattern.s, replacement.s, &(tostring[0]),
				&result) < 0) {
			pattern.s[pattern.len] = '!';
			replacement.s[replacement.len] = '!';
			LM_ERR("Regexp replace failed\n");
			continue;
		}
		LM_DBG("Resulted in replacement: '%.*s'\n",
		       result.len, ZSW(result.s));
		pattern.s[pattern.len] = '!';
		replacement.s[replacement.len] = '!';

		if (param.len > 0) {
			if (result.len + param.len > MAX_URI_SIZE - 1) {
				LM_ERR("URI is too long\n");
				continue;
			}
			new_result.s = &(new_uri[0]);
			new_result.len = MAX_URI_SIZE;
			if (add_uri_param(&result, &param, &new_result) == 0) {
				LM_ERR("Parsing of URI <%.*s> failed\n",
				       result.len, result.s);
				continue;
			}
			if (new_result.len > 0) {
				result = new_result;
			}
		}

		if (first) {
			if (set_ruri(_msg, &result) == -1) {
				goto done;
			}
			set_ruri_q(_msg, q);
			first = 0;
			curr_prio = ((naptr->order) << 16) + naptr->pref;
		} else {
			priority = ((naptr->order) << 16) + naptr->pref;
			if (priority > curr_prio) {
				q = q - 10;
				curr_prio = priority;
			}
			if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
				goto done;
			}
		}
	}

done:
	free_rdata_list(head);
	return first ? -1 : 1;
}
Exemple #7
0
/*
 * Do loose routing as defined in RFC3261
 */
int loose_route(struct sip_msg* _m)
{
	int ret;

	ctx_routing_set(0);

	if (find_first_route(_m) != 0) {
		LM_DBG("There is no Route HF\n");
		return -1;
	}

	if (parse_sip_msg_uri(_m)<0) {
		LM_ERR("failed to parse Request URI\n");
		return -1;
	}

	ret = is_preloaded(_m);
	if (ret < 0) {
		return -1;
	} else if (ret == 1) {
		return after_loose(_m, 1);
	} else {
#ifdef ENABLE_USER_CHECK
		if (is_myself(&_m->parsed_uri.user, &_m->parsed_uri.host,
		_m->parsed_uri.port_no) && !(_m->parsed_uri.gr.s && _m->parsed_uri.gr.len)) {
#else
		if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no) && !(_m->parsed_uri.gr.s && _m->parsed_uri.gr.len)) {
#endif
			return after_strict(_m);
		} else {
			return after_loose(_m, 0);
		}
	}
}


int get_route_params(struct sip_msg *msg, str *val)
{
	if(msg==NULL)
		return -1;

	/* check if params are present */
	if ( (val=ctx_rrparam_get())==NULL )
		return -1;

	return 0;
}


int check_route_param(struct sip_msg * msg, regex_t* re)
{
	regmatch_t pmatch;
	char bk;
	str params;
	str *rparams;

	/* check if params are present */
	if ( (rparams=ctx_rrparam_get())==NULL || rparams->len==0)
		return -1;

	/* include also the first ';' */
	for( params=*rparams ; params.s[0]!=';' ; params.s--,params.len++ );

	/* do the well-known trick to convert to null terminted */
	bk = params.s[params.len];
	params.s[params.len] = 0;
	LM_DBG("params are <%s>\n", params.s);
	if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
		params.s[params.len] = bk;
		return -1;
	} else {
		params.s[params.len] = bk;
		return 0;
	}
}
Exemple #8
0
/*
 * Find if Request URI has a given parameter with matching value
 */
int uri_param_2(struct sip_msg* _msg, char* _param, char* _value)
{
	str param, value, t;

	param_hooks_t hooks;
	param_t* params;


	if (get_str_fparam(&param, _msg, (fparam_t *)_param) < 0) {
		ERR("is_user: failed to recover 1st parameter.\n");
		return -1;
	}
	if (_value) {
		if (get_str_fparam(&value, _msg, (fparam_t *)_value) < 0) {
			ERR("is_user: failed to recover 1st parameter.\n");
			return -1;
		}
	} else {
	    value.s = 0;
	}

	if (parse_sip_msg_uri(_msg) < 0) {
	        LOG(L_ERR, "uri_param(): ruri parsing failed\n");
	        return -1;
	}

	t = _msg->parsed_uri.params;

	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
	        LOG(L_ERR, "uri_param(): ruri parameter parsing failed\n");
	        return -1;
	}

	while (params) {
		if ((params->name.len == param.len) &&
		    (strncmp(params->name.s, param.s, param.len) == 0)) {
			if (value.s) {
				if ((value.len == params->body.len) &&
				    strncmp(value.s, params->body.s, value.len) == 0) {
					goto ok;
				} else {
					goto nok;
				}
			} else {
				if (params->body.len > 0) {
					goto nok;
				} else {
					goto ok;
				}
			}
		} else {
			params = params->next;
		}
	}
	
nok:
	free_params(params);
	return -1;

ok:
	free_params(params);
	return 1;
}
Exemple #9
0
/*
 * Adds a new parameter to Request URI
 */
int add_uri_param(struct sip_msg* _msg, char* _param, char* _s2)
{
	str param, *cur_uri, new_uri;
	struct sip_uri *parsed_uri;
	char *at;

	if (get_str_fparam(&param, _msg, (fparam_t *)_param) < 0) {
	    ERR("add_uri_param: failed to recover parameter.\n");
	    return -1;
	}

	if (param.len == 0) {
		return 1;
	}

	if (parse_sip_msg_uri(_msg) < 0) {
	        LOG(L_ERR, "add_uri_param(): ruri parsing failed\n");
	        return -1;
	}

	parsed_uri = &(_msg->parsed_uri);

	/* if current ruri has no headers, pad param at the end */
	if (parsed_uri->headers.len == 0) {
		cur_uri =  GET_RURI(_msg);
		new_uri.len = cur_uri->len + param.len + 1;
		if (new_uri.len > MAX_URI_SIZE) {
			LOG(L_ERR, "add_uri_param(): new ruri too long\n");
			return -1;
		}
		new_uri.s = pkg_malloc(new_uri.len);
		if (new_uri.s == 0) {
			LOG(L_ERR, "add_uri_param(): Memory allocation failure\n");
			return -1;
		}
		memcpy(new_uri.s, cur_uri->s, cur_uri->len);
		*(new_uri.s + cur_uri->len) = ';';
		memcpy(new_uri.s + cur_uri->len + 1, param.s, param.len);
		if (rewrite_uri(_msg, &new_uri ) == 1) {
			goto ok;
		} else {
			goto nok;
		}
	}

	/* otherwise take the long path */
	new_uri.len = 4 +
		(parsed_uri->user.len ? parsed_uri->user.len + 1 : 0) +
		(parsed_uri->passwd.len ? parsed_uri->passwd.len + 1 : 0) +
		parsed_uri->host.len +
		(parsed_uri->port.len ? parsed_uri->port.len + 1 : 0) +
		parsed_uri->params.len + param.len + 1 +
		parsed_uri->headers.len + 1;
	if (new_uri.len > MAX_URI_SIZE) {
	        LOG(L_ERR, "add_uri_param(): new ruri too long\n");
		return -1;
	}

	new_uri.s = pkg_malloc(new_uri.len);
	if (new_uri.s == 0) {
		LOG(L_ERR, "add_uri_param(): Memory allocation failure\n");
		return -1;
	}

	at = new_uri.s;
	memcpy(at, "sip:", 4);
	at = at + 4;
	if (parsed_uri->user.len) {
		memcpy(at, parsed_uri->user.s, parsed_uri->user.len);
		if (parsed_uri->passwd.len) {
			*at = ':';
			at = at + 1;
			memcpy(at, parsed_uri->passwd.s, parsed_uri->passwd.len);
			at = at + parsed_uri->passwd.len;
		};
		*at = '@';
		at = at + 1;
	}
	memcpy(at, parsed_uri->host.s, parsed_uri->host.len);
	at = at + parsed_uri->host.len;
	if (parsed_uri->port.len) {
		*at = ':';
		at = at + 1;
		memcpy(at, parsed_uri->port.s, parsed_uri->port.len);
		at = at + parsed_uri->port.len;
	}
	memcpy(at, parsed_uri->params.s, parsed_uri->params.len);
	at = at + parsed_uri->params.len;
	*at = ';';
	at = at + 1;
	memcpy(at, param.s, param.len);
	at = at + param.len;
	*at = '?';
	at = at + 1;
	memcpy(at, parsed_uri->headers.s, parsed_uri->headers.len);

	if (rewrite_uri(_msg, &new_uri) == 1) {
		goto ok;
	}

nok:
	pkg_free(new_uri.s);
	return -1;

ok:
	pkg_free(new_uri.s);
	return 1;
}
/*
 * Get number portability parameter from Request-Line
 * param msg SIP message
 * param rn Routing number
 * param rnbufsize Size of rn buffer
 * param cic Carrier identification code
 * param cicbufsize Size of cic buffer
 * param npdi NP database dip indicator
 * return 0 success, 1 not use NP or without NP parameters, -1 failure
 */
int ospGetNpParameters(
    struct sip_msg* msg,
    char* rn,
    int rnbufsize,
    char* cic,
    int cicbufsize,
    int* npdi)
{
    str sv;
    param_hooks_t phooks;
    param_t* params = NULL;
    param_t* pit;
    int result = -1;

    if (((rn != NULL) && (rnbufsize > 0)) && ((cic != NULL) && (cicbufsize > 0)) && (npdi != NULL)) {
        rn[0] = '\0';
        cic[0] = '\0';
        *npdi = 0;

        if (_osp_use_np != 0) {
            if (parse_sip_msg_uri(msg) >= 0) {
                switch (msg->parsed_uri.type) {
                case TEL_URI_T:
                case TELS_URI_T:
                    sv = msg->parsed_uri.params;
                    break;
                case ERROR_URI_T:
                case SIP_URI_T:
                case SIPS_URI_T:
                default:
                    sv = msg->parsed_uri.user;
                    break;
                }
                parse_params(&sv, CLASS_ANY, &phooks, &params);
                for (pit = params; pit; pit = pit->next) {
                    if ((pit->name.len == OSP_RN_SIZE) &&
                        (strncasecmp(pit->name.s, OSP_RN_NAME, OSP_RN_SIZE) == 0) &&
                        (rn[0] == '\0'))
                    {
                        ospCopyStrToBuffer(&pit->body, rn, rnbufsize);
                    } else if ((pit->name.len == OSP_CIC_SIZE) &&
                        (strncasecmp(pit->name.s, OSP_CIC_NAME, OSP_CIC_SIZE) == 0) &&
                        (cic[0] == '\0'))
                    {
                        ospCopyStrToBuffer(&pit->body, cic, cicbufsize);
                    } else if ((pit->name.len == OSP_NPDI_SIZE) &&
                        (strncasecmp(pit->name.s, OSP_NPDI_NAME, OSP_NPDI_SIZE) == 0))
                    {
                        *npdi = 1;
                    }
                }
                if (params != NULL) {
                    free_params(params);
                }
                if ((rn[0] != '\0') || (cic[0] != '\0') || (*npdi != 0)) {
                    result = 0;
                } else {
                    LM_DBG("without number portability parameters\n");
                    result = 1;
                }
            } else {
                LM_ERR("failed to parse Request-Line URI\n");
            }
        } else {
            LM_DBG("do not use number portability\n");
            result = 1;
        }
    } else {
        LM_ERR("bad parameters to parse number portability parameters\n");
    }

    return result;
}
/*
 * Get operator name from Request-Line
 * param msg SIP message
 * param type Operator name type
 * param name Operator name buffer
 * param namebufsize Size of name buffer
 * return 0 success, 1 not use NP or without operator name, -1 failure
 */
int ospGetOperatorName(
    struct sip_msg* msg,
    OSPE_OPERATOR_NAME type,
    char* name,
    int namebufsize)
{
    str sv;
    param_hooks_t phooks;
    param_t* params = NULL;
    param_t* pit;
    int result = -1;

    if (((name != NULL) && (namebufsize > 0))) {
        name[0] = '\0';

        if (_osp_use_np != 0) {
            if (parse_sip_msg_uri(msg) >= 0) {
                switch (msg->parsed_uri.type) {
                case TEL_URI_T:
                case TELS_URI_T:
                    sv = msg->parsed_uri.params;
                    break;
                case ERROR_URI_T:
                case SIP_URI_T:
                case SIPS_URI_T:
                default:
                    sv = msg->parsed_uri.user;
                    break;
                }
                parse_params(&sv, CLASS_ANY, &phooks, &params);
                for (pit = params; pit; pit = pit->next) {
                    switch (type) {
                    case OSPC_OPNAME_SPID:
                        if ((pit->name.len == OSP_SPID_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_SPID_NAME, OSP_SPID_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    case OSPC_OPNAME_OCN:
                        if ((pit->name.len == OSP_OCN_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_OCN_NAME, OSP_OCN_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    case OSPC_OPNAME_SPN:
                        if ((pit->name.len == OSP_SPN_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_SPN_NAME, OSP_SPN_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    case OSPC_OPNAME_ALTSPN:
                        if ((pit->name.len == OSP_ALTSPN_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_ALTSPN_NAME, OSP_ALTSPN_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    case OSPC_OPNAME_MCC:
                        if ((pit->name.len == OSP_MCC_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_MCC_NAME, OSP_MCC_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    case OSPC_OPNAME_MNC:
                        if ((pit->name.len == OSP_MNC_SIZE) &&
                            (strncasecmp(pit->name.s, OSP_MNC_NAME, OSP_MNC_SIZE) == 0) &&
                            (name[0] == '\0'))
                        {
                            ospCopyStrToBuffer(&pit->body, name, namebufsize);
                        }
                        break;
                    default:
                        break;
                    }
                }
                if (params != NULL) {
                    free_params(params);
                }
                if (name[0] != '\0') {
                    result = 0;
                } else {
                    LM_DBG("without operator name\n");
                    result = 1;
                }
            } else {
                LM_ERR("failed to parse Request-Line URI\n");
            }
        } else {
            LM_DBG("do not use number portability\n");
            result = 1;
        }
    } else {
        LM_ERR("bad parameters to parse operator name\n");
    }

    return result;
}
Exemple #12
0
int perl_exec2(struct sip_msg* _msg, char* fnc, char* mystr) {
	int retval;
	SV *m;
	str reason;

	app_perl_reset_interpreter();

	dSP;

	if (!perl_checkfnc(fnc)) {
		LM_ERR("unknown perl function called.\n");
		reason.s = "Internal error";
		reason.len = sizeof("Internal error")-1;
		if (slb.freply(_msg, 500, &reason) == -1)
		{
			LM_ERR("failed to send reply\n");
		}
		return -1;
	}
	
	switch ((_msg->first_line).type) {
	case SIP_REQUEST:
		if (parse_sip_msg_uri(_msg) < 0) {
			LM_ERR("failed to parse Request-URI\n");

			reason.s = "Bad Request-URI";
			reason.len = sizeof("Bad Request-URI")-1;
			if (slb.freply(_msg, 400, &reason) == -1) {
				LM_ERR("failed to send reply\n");
			}
			return -1;
		}
		break;
	case SIP_REPLY:
		break;
	default:
		LM_ERR("invalid firstline");
		return -1;
	}

	ENTER;				/* everything created after here */
	SAVETMPS;			/* ...is a temporary variable.   */
	PUSHMARK(SP);		/* remember the stack pointer    */

	m = sv_newmortal();
	sv_setref_pv(m, "Kamailio::Message", (void *)_msg);
	SvREADONLY_on(SvRV(m));

	XPUSHs(m);			/* Our reference to the stack... */

	if (mystr)
		XPUSHs(sv_2mortal(newSVpv(mystr, strlen(mystr))));
					/* Our string to the stack... */

	PUTBACK;			/* make local stack pointer global */

	call_pv(fnc, G_EVAL|G_SCALAR);		/* call the function     */
	SPAGAIN;			/* refresh stack pointer         */
	/* pop the return value from stack */
	retval = POPi;

	PUTBACK;
	FREETMPS;			/* free that return value        */
	LEAVE;				/* ...and the XPUSHed "mortal" args.*/

	return retval;
}
Exemple #13
0
int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
	char *user_s;
	int user_len, i, j, first;
	char name[MAX_DOMAIN_SIZE];
	char uri[MAX_URI_SIZE];
	char new_uri[MAX_URI_SIZE];
	unsigned int priority, curr_prio;
	qvalue_t q;

	struct rdata* head;
	struct rdata* l;
	struct naptr_rdata* naptr;

	str pattern, replacement, result, new_result;

	char string[17];

	str *suffix, *service;

	suffix = (str*)_suffix;
	service = (str*)_service;

	if (parse_sip_msg_uri(_msg) < 0) {
		LOG(L_ERR, "enum_query(): uri parsing failed\n");
		return -1;
	}

	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
		LOG(L_ERR, "enum_query(): uri user is not an E164 number\n");
		return -1;
	}

	user_s = _msg->parsed_uri.user.s;
	user_len = _msg->parsed_uri.user.len;

	memcpy(&(string[0]), user_s, user_len);
	string[user_len] = (char)0;

	j = 0;
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
	}

	memcpy(name + j, suffix->s, suffix->len + 1);

	head = get_record(name, T_NAPTR);

	if (head == 0) {
		DBG("enum_query(): No NAPTR record found for %s.\n", name);
		return -1;
	}

	naptr_sort(&head);

	q = MAX_Q - 10;
	curr_prio = 0;
	first = 1;

	for (l = head; l; l = l->next) {

		if (l->type != T_NAPTR) continue; /*should never happen*/
		naptr = (struct naptr_rdata*)l->rdata;
		if (naptr == 0) {
			LOG(L_CRIT, "enum_query: BUG: null rdata\n");
			continue;
		}

		DBG("enum_query(): order %u, pref %u, flen %u, flags '%.*s', slen %u, "
		    "services '%.*s', rlen %u, regexp '%.*s'\n", naptr->order, naptr->pref,
		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
		    naptr->services_len,
		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
		    (int)(naptr->regexp_len), ZSW(naptr->regexp));

		if (sip_match(naptr, service) == 0) continue;

		if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
				       &pattern, &replacement) < 0) {
			LOG(L_ERR, "enum_query(): parsing of NAPTR regexp failed\n");
			continue;
		}
		result.s = &(uri[0]);
		result.len = MAX_URI_SIZE;
		/* Avoid making copies of pattern and replacement */
		pattern.s[pattern.len] = (char)0;
		replacement.s[replacement.len] = (char)0;
		if (reg_replace(pattern.s, replacement.s, &(string[0]),
				&result) < 0) {
			pattern.s[pattern.len] = '!';
			replacement.s[replacement.len] = '!';
			LOG(L_ERR, "enum_query(): regexp replace failed\n");
			continue;
		}
		DBG("enum_query(): resulted in replacement: '%.*s'\n",
		    result.len, ZSW(result.s));
		pattern.s[pattern.len] = '!';
		replacement.s[replacement.len] = '!';
		
		if (param.len > 0) {
			if (result.len + param.len > MAX_URI_SIZE - 1) {
				LOG(L_ERR, "ERROR: enum_query(): URI is too long\n");
				continue;
			}
			new_result.s = &(new_uri[0]);
			new_result.len = MAX_URI_SIZE;
			if (add_uri_param(&result, &param, &new_result) == 0) {
				LOG(L_ERR, "ERROR: enum_query(): Parsing of URI failed\n");
				continue;
			}
			if (new_result.len > 0) {
				result = new_result;
			}
		}

		if (first) {
			if (rewrite_uri(_msg, &result) == -1) {
				goto done;
			}
			set_ruri_q(q);
			first = 0;
			curr_prio = ((naptr->order) << 16) + naptr->pref;
		} else {
			priority = ((naptr->order) << 16) + naptr->pref;
			if (priority > curr_prio) {
				q = q - 10;
				curr_prio = priority;
			}
			if (append_branch(_msg, &result, 0, q, 0, 0) == -1) {
				goto done;
			}
		}
	}

done:
	free_rdata_list(head);
	return first ? -1 : 1;
}
Exemple #14
0
/*
 * Send Radius request to verify destination and generate AVPs from
 * reply items of positive response.
 */
int verify_destination(struct sip_msg* _msg, char* s1, char* s2)
{
	aaa_message *send = NULL, *received = NULL;
    uint32_t service;

    /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
    if (parse_sip_msg_uri(_msg) < 0) {
        LM_ERR("error while parsing Request-URI\n");
		return -1;
    }

	if ((send = proto.create_aaa_message(conn, AAA_AUTH)) == NULL) {
		LM_ERR("failed to create new aaa message for auth\n");
		return -1;
	}

    if (proto.avp_add(conn, send, &attrs[A_USER_NAME],
		       _msg->parsed_uri.host.s,
		       _msg->parsed_uri.host.len, 0)) {
		LM_ERR("error adding PW_USER_NAME\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_URI_USER],
		       _msg->parsed_uri.user.s,
		       _msg->parsed_uri.user.len, 0)) {
		LM_ERR("error adding PW_SIP_URI_USER\n");
		goto err;
    }

    /* Add From Tag */
    if (parse_from_header(_msg) < 0) {
		LM_ERR("error while parsing From header field\n");
		goto err;
    }

    if ((_msg->from==NULL) || (get_from(_msg) == NULL) ||
				(get_from(_msg)->tag_value.s == NULL) ||
				(get_from(_msg)->tag_value.len <= 0)) {
		LM_ERR("error while accessing From header tag\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_FROM_TAG],
		       get_from(_msg)->tag_value.s,
		       get_from(_msg)->tag_value.len, 0)) {
		LM_ERR("error adding PW_SIP_FROM_TAG\n");
		goto err;
    }

    /* Add Call-Id */
    if ((parse_headers(_msg, HDR_CALLID_F, 0) == -1) ||
	(_msg->callid == NULL) || (_msg->callid->body.s == NULL) ||
	(_msg->callid->body.len <= 0)) {
		LM_ERR("error while accessing Call-Id\n");
		goto err;
    }

    if (proto.avp_add(conn, send, &attrs[A_SIP_CALL_ID],
		       _msg->callid->body.s,
		       _msg->callid->body.len, 0)) {
		LM_ERR("error adding PW_SIP_CALL_ID\n");
		goto err;
    }

    /* Add Service-Type */
    service = vals[V_SIP_VERIFY_DESTINATION].value;
    if (proto.avp_add(conn, send, &attrs[A_SERVICE_TYPE],
		       &service, -1, 0)) {
		LM_ERR("error adding PW_SERVICE_TYPE\n");
		goto err;
    }

    /* Send Request and generate AVPs of positive reply */
    if (!proto.send_aaa_request(conn, send, &received)) {
		LM_DBG("success\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return 1;
    }

	LM_DBG("failure\n");

err:
    if (send)
		proto.destroy_aaa_message(conn, send);
    if (received)
		proto.destroy_aaa_message(conn, received);
    return -1;
}
Exemple #15
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) {
			LM_ERR("failed to parse From header field\n");
			return -1;
		}

		uri = &get_from(msg)->uri;
		if (parse_uri(uri->s, uri->len, &puri) < 0) {
			LM_ERR("failed to parse 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) {
			LM_ERR("failed to parse Request-URI\n");
			return -1;
		}

		if (msg->parsed_uri.user.len == 0) {
			LM_ERR("missing Request-URI user");
			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) {
			LM_ERR("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:
		LM_ERR("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) {
		LM_ERR("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)) {
		LM_ERR("failed to add PW_USER_NAME\n");
		goto error;
	}

	if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
		LM_ERR("failed to add PW_SERVICE_TYPE\n");
		goto error;
	}

	if (rc_auth(rh, 0, send, &received, rad_msg) == OK_RC) {
		LM_DBG("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) {
					LM_ERR("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) {
				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 );
			}

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

		rc_avpair_free(received);
		return 1;
	} else {
		LM_ERR("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;
}
Exemple #16
0
static int imc_manager(struct sip_msg* msg, char *str1, char *str2)
{
	imc_cmd_t cmd;
	str body;
	struct sip_uri from_uri, *pto_uri=NULL, *pfrom_uri=NULL;
	struct to_body *pfrom;

	if ( get_body( msg, &body)!=0 || body.len==0)
	{
		LM_DBG("empty body!\n");
		goto error;
	}

	if(parse_sip_msg_uri(msg)<0)
	{
		LM_ERR("failed to parse r-uri\n");
		goto error;
	}

	pto_uri=&msg->parsed_uri;

	if(parse_from_header(msg)<0)
	{
		LM_ERR("failed to parse From header\n");
		goto error;
	}
	pfrom = (struct to_body*)msg->from->parsed;
	if(parse_uri(pfrom->uri.s, pfrom->uri.len, &from_uri)<0){
		LM_ERR("failed to parse From URI\n");
		goto error;
	}
	pfrom_uri=&from_uri;

	if(body.s[0]== imc_cmd_start_char)
	{
		LM_DBG("found command\n");
		if(imc_parse_cmd(body.s, body.len, &cmd)<0)
		{
			LM_ERR("failed to parse imc cmd!\n");
			goto error;
		}

		switch(cmd.type)
		{
		case IMC_CMDID_CREATE:
			if(imc_handle_create(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'create'\n");
				goto error;
			}
		break;
		case IMC_CMDID_JOIN:
			if(imc_handle_join(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'join'\n");
				goto error;
			}
		break;
		case IMC_CMDID_INVITE:
			if(imc_handle_invite(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'invite'\n");
				goto error;
			}
		break;
		case IMC_CMDID_ACCEPT:
			if(imc_handle_accept(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'accept'\n");
				goto error;
			}
		break;
		case IMC_CMDID_DENY:
			if(imc_handle_deny(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'deny'\n");
				goto error;
			}
		break;
		case IMC_CMDID_REMOVE:
			if(imc_handle_remove(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'remove'\n");
				goto error;
			}
		break;
		case IMC_CMDID_EXIT:
			if(imc_handle_exit(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'exit'\n");
				goto error;
			}
		break;
		case IMC_CMDID_LIST:
			if(imc_handle_list(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'list'\n");
				goto error;
			}
		break;
		case IMC_CMDID_DESTROY:
			if(imc_handle_destroy(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'destroy'\n");
				goto error;
			}
		break;
		case IMC_CMDID_HELP:
			if(imc_handle_help(msg, &cmd, &pfrom->uri,
			(msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
			{
				LM_ERR("failed to handle 'help'\n");
				goto error;
			}
		break;
		default:
			if(imc_handle_unknown(msg, &cmd, &pfrom->uri,
			(msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
			{
				LM_ERR("failed to handle 'unknown'\n");
				goto error;
			}
		}

		goto done;
	}

	if(imc_handle_message(msg, &body, pfrom_uri, pto_uri)<0)
	{
		LM_ERR("failed to handle 'message'\n");
		goto error;
	}

done:
	return 1;

error:

	return -1;
}
Exemple #17
0
int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner)
{
	str user_s, table_s, uri_s;
	int nr_keys;
	struct sip_uri *puri;
	struct sip_uri turi;
	db_key_t db_keys[4];
	db_val_t db_vals[4];
	db_key_t db_cols[1];
	db1_res_t* db_res = NULL;

	if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0)
	{
		LM_ERR("invalid table parameter");
		return -1;
	}

	/* init */
	nr_keys = 0;
	db_cols[0]=&new_uri_column;
	
	if(_owner)
	{
		memset(&turi, 0, sizeof(struct sip_uri));
		if(fixup_get_svalue(_msg, (gparam_p)_owner, &uri_s)!=0)
		{
			LM_ERR("invalid owner uri parameter");
			return -1;
		}
		if(parse_uri(uri_s.s, uri_s.len, &turi)!=0)
		{
			LM_ERR("bad owner SIP address!\n");
			goto err_server;
		}
		LM_DBG("using user id [%.*s]\n", uri_s.len, uri_s.s);
		puri = &turi;
	} else {
		/* take username@domain from From header */
		if ( (puri = parse_from_uri(_msg ))==NULL )
		{
			LM_ERR("failed to parse FROM header\n");
			goto err_server;
		}
	}
		
	db_keys[nr_keys]=&user_column;
	db_vals[nr_keys].type = DB1_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = puri->user.s;
	db_vals[nr_keys].val.str_val.len = puri->user.len;
	nr_keys++;

	if(use_domain>=1)
	{
		db_keys[nr_keys]=&domain_column;
		db_vals[nr_keys].type = DB1_STR;
		db_vals[nr_keys].nul = 0;
		db_vals[nr_keys].val.str_val.s = puri->host.s;
		db_vals[nr_keys].val.str_val.len = puri->host.len;
		nr_keys++;
		
		if (dstrip_s.s!=NULL && dstrip_s.len>0
			&& dstrip_s.len<puri->host.len
			&& strncasecmp(puri->host.s,dstrip_s.s,dstrip_s.len)==0)
		{
			db_vals[nr_keys].val.str_val.s   += dstrip_s.len;
			db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
		}
	}
	/* take sd from r-uri */
	if (parse_sip_msg_uri(_msg) < 0)
	{
		LM_ERR("failed to parsing Request-URI\n");
		goto err_server;
	}
	
	db_keys[nr_keys]=&sd_user_column;
	db_vals[nr_keys].type = DB1_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.user.s;
	db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.user.len;
	nr_keys++;
	
	if(use_domain>=2)
	{
		db_keys[nr_keys]=&sd_domain_column;
		db_vals[nr_keys].type = DB1_STR;
		db_vals[nr_keys].nul = 0;
		db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.host.s;
		db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.host.len;
		nr_keys++;
		
		if (dstrip_s.s!=NULL && dstrip_s.len>0
			&& dstrip_s.len<_msg->parsed_uri.host.len
			&& strncasecmp(_msg->parsed_uri.host.s,dstrip_s.s,dstrip_s.len)==0)
		{
			db_vals[nr_keys].val.str_val.s   += dstrip_s.len;
			db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
		}
	}
	
	db_funcs.use_table(db_handle, &table_s);
	if(db_funcs.query(db_handle, db_keys, NULL, db_vals, db_cols,
		nr_keys /*no keys*/, 1 /*no cols*/, NULL, &db_res)!=0)
	{
		LM_ERR("failed to query database\n");
		goto err_server;
	}

	if (RES_ROW_N(db_res)<=0 || RES_ROWS(db_res)[0].values[0].nul != 0)
	{
		LM_DBG("no sip addres found for R-URI\n");
		if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0)
			LM_DBG("failed to free result of query\n");
		return -1;
	}

	user_s.s = useruri_buf+4;
	switch(RES_ROWS(db_res)[0].values[0].type)
	{ 
		case DB1_STRING:
			strcpy(user_s.s, 
				(char*)RES_ROWS(db_res)[0].values[0].val.string_val);
			user_s.len = strlen(user_s.s);
		break;
		case DB1_STR:
			strncpy(user_s.s, 
				(char*)RES_ROWS(db_res)[0].values[0].val.str_val.s,
				RES_ROWS(db_res)[0].values[0].val.str_val.len);
			user_s.len = RES_ROWS(db_res)[0].values[0].val.str_val.len;
			user_s.s[user_s.len] = '\0';
		break;
		case DB1_BLOB:
			strncpy(user_s.s, 
				(char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s,
				RES_ROWS(db_res)[0].values[0].val.blob_val.len);
			user_s.len = RES_ROWS(db_res)[0].values[0].val.blob_val.len;
			user_s.s[user_s.len] = '\0';
		default:
			LM_ERR("unknown type of DB new_uri column\n");
			if (db_res != NULL && db_funcs.free_result(db_handle, db_res) < 0)
			{
				LM_DBG("failed to free result of query\n");
			}
			goto err_server;
	}
	
	/* check 'sip:' */
	if(user_s.len<4 || strncmp(user_s.s, "sip:", 4))
	{
		memcpy(useruri_buf, "sip:", 4);
		user_s.s -= 4;
		user_s.len += 4;
	}

	/**
	 * Free the result because we don't need it anymore
	 */
	if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0)
		LM_DBG("failed to free result of query\n");

	/* set the URI */
	LM_DBG("URI of sd from R-URI [%s]\n", user_s.s);
	if(rewrite_ruri(_msg, user_s.s)<0)
	{
		LM_ERR("failed to replace the R-URI\n");
		goto err_server;
	}

	return 1;

err_server:
	return -1;
}
Exemple #18
0
static int opt_reply(struct sip_msg* _msg, char* _foo, char* _bar) {
	str rpl_hf;
	int offset = 0;

	/* check if it is called for an OPTIONS request */
	if (_msg->REQ_METHOD!=METHOD_OPTIONS) {
		LM_ERR("called for non-OPTIONS request\n");
		return -1;
	}
	if(_msg->parsed_uri_ok==0 && parse_sip_msg_uri(_msg)<0)
	{
		LM_ERR("ERROR while parsing the R-URI\n");
		return -1;
	}
	/* FIXME: should we additionally check if ruri == server addresses ?! */
	if (_msg->parsed_uri.user.len != 0) {
		LM_ERR("ruri contains username\n");
		return -1;
	}

	/* calculate the length and allocated the mem */
	rpl_hf.len = ACPT_STR_LEN + ACPT_ENC_STR_LEN + ACPT_LAN_STR_LEN + 
			SUPT_STR_LEN + 4*HF_SEP_STR_LEN + acpt_s.len + acpt_enc_s.len + 
			acpt_lan_s.len + supt_s.len;
	rpl_hf.s = (char*)pkg_malloc(rpl_hf.len);
	if (!rpl_hf.s) {
		LM_CRIT("out of pkg memory\n");
		goto error;
	}

	/* create the header fields */
	memcpy(rpl_hf.s, ACPT_STR, ACPT_STR_LEN);
	offset = ACPT_STR_LEN;
	memcpy(rpl_hf.s + offset, acpt_s.s, acpt_s.len);
	offset += acpt_s.len;
	memcpy(rpl_hf.s + offset, HF_SEP_STR, HF_SEP_STR_LEN);
	offset += HF_SEP_STR_LEN;
	memcpy(rpl_hf.s + offset, ACPT_ENC_STR, ACPT_ENC_STR_LEN);
	offset += ACPT_ENC_STR_LEN;
	memcpy(rpl_hf.s + offset, acpt_enc_s.s, acpt_enc_s.len);
	offset += acpt_enc_s.len;
	memcpy(rpl_hf.s + offset, HF_SEP_STR, HF_SEP_STR_LEN);
	offset += HF_SEP_STR_LEN;
	memcpy(rpl_hf.s + offset, ACPT_LAN_STR, ACPT_LAN_STR_LEN);
	offset += ACPT_LAN_STR_LEN;
	memcpy(rpl_hf.s + offset, acpt_lan_s.s, acpt_lan_s.len);
	offset += acpt_lan_s.len;
	memcpy(rpl_hf.s + offset, HF_SEP_STR, HF_SEP_STR_LEN);
	offset += HF_SEP_STR_LEN;
	memcpy(rpl_hf.s + offset, SUPT_STR, SUPT_STR_LEN);
	offset += SUPT_STR_LEN;
	memcpy(rpl_hf.s + offset, supt_s.s, supt_s.len);
	offset += supt_s.len;
	memcpy(rpl_hf.s + offset, HF_SEP_STR, HF_SEP_STR_LEN);

#ifdef EXTRA_DEBUG
	offset += HF_SEP_STR_LEN;
	if (offset != rpl_hf.len) {
		LM_CRIT("headerlength (%i) != offset (%i)\n", rpl_hf.len, offset);
		abort();
	}
#endif


	if (add_lump_rpl( _msg, rpl_hf.s, rpl_hf.len,
	LUMP_RPL_HDR|LUMP_RPL_NODUP)!=0) {
		if (slb.reply(_msg, 200, &opt_200_rpl) == -1) {
			LM_ERR("failed to send 200 via send_reply\n");
			return -1;
		}
		else
			return 0;
	} else {
		pkg_free(rpl_hf.s);
		LM_ERR("add_lump_rpl failed\n");
	}

error:
	if (slb.reply(_msg, 500, &opt_500_rpl) == -1) {
		LM_ERR("failed to send 500 via send_reply\n");
		return -1;
	}
	else
		return 0;
}
Exemple #19
0
/*
 * See documentation in README file.
 */
int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
	char *user_s;
	int user_len, i, j;
	char name[MAX_DOMAIN_SIZE];
	char string[17];
	gparam_p gp = NULL;
	pv_value_t value;

	str __suffix = {0, 0}, __service = {0, 0};

	/* Use the suffix module parameter */
	if (_suffix == NULL) {
		__suffix.s = suffix.s;
		__suffix.len = suffix.len;
	} else {
		gp = (gparam_p) _suffix;

		if (gp->type == GPARAM_TYPE_PVS) {
			if (pv_get_spec_value(_msg, gp->v.pvs, &value) != 0 ||
				value.flags & PV_VAL_NULL || value.flags & PV_VAL_EMPTY) {
				LM_ERR("No PV or NULL value specified for suffix\n");
				return E_CFG;
			}

			if (value.flags & PV_VAL_STR) {
				__suffix.s = value.rs.s;
				__suffix.len = value.rs.len;
			} else {
				LM_ERR("Unsupported PV value type\n");
				return E_CFG;
			}
		} else if (gp->type == GPARAM_TYPE_STR) {
			__suffix.s = gp->v.sval.s;
			__suffix.len = gp->v.sval.len;
		}
	}

	/* Use the internal service */
	if (_service == NULL) {
		__service.s = service.s;
		__service.len = service.len;
	} else {
		gp = (gparam_p) _service;

		if (gp->type == GPARAM_TYPE_PVS) {
			if (pv_get_spec_value(_msg, gp->v.pvs, &value) != 0 ||
				value.flags & PV_VAL_NULL || value.flags & PV_VAL_EMPTY) {
				LM_ERR("No PV or NULL value specified for suffix\n");
				return E_CFG;
			}

			if (value.flags & PV_VAL_STR) {
				__service.s = value.rs.s;
				__service.len = value.rs.len;
			} else {
				LM_ERR("Unsupported PV value type\n");
				return E_CFG;
			}
		} else if (gp->type == GPARAM_TYPE_STR) {
			__service.s = gp->v.sval.s;
			__service.len = gp->v.sval.len;
		}
	}

	if (parse_sip_msg_uri(_msg) < 0) {
		LM_ERR("Parsing of R-URI failed\n");
		return -1;
	}

	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
		LM_ERR("R-URI user is not an E164 number\n");
		return -1;
	}

	user_s = _msg->parsed_uri.user.s;
	user_len = _msg->parsed_uri.user.len;

	memcpy(&(string[0]), user_s, user_len);
	string[user_len] = (char)0;

	j = 0;
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
	}

	memcpy(name + j, __suffix.s, __suffix.len + 1);

	return do_query(_msg, string, name, &__service);
}
Exemple #20
0
int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
{
	str dest = {0};
	int ret = 0;
	struct sip_uri next_hop, *u;
	struct dest_info dst;
	char *p;

	if (pu)
	{
		if (fixup_get_svalue(msg, pu, &dest))
		{
			LM_ERR("cannot get the destination parameter\n");
			return -1;
		}
	}

	init_dest_info(&dst);

	if (dest.len <= 0)
	{
		/*get next hop uri uri*/
		if (msg->dst_uri.len) {
			ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
							&next_hop);
			u = &next_hop;
		} else {
			ret = parse_sip_msg_uri(msg);
			u = &msg->parsed_uri;
		}

		if (ret<0) {
			LM_ERR("send() - bad_uri dropping packet\n");
			ret=E_BUG;
			goto error;
		}
	}
	else
	{
		u = &next_hop;
		u->port_no = 5060;
		u->host = dest;
		p = memchr(dest.s, ':', dest.len);
		if (p)
		{
			u->host.len = p - dest.s;
			p++;
			u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
		}
	}

	ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
				&dst.proto);
	if(ret!=0) {
		LM_ERR("failed to resolve [%.*s]\n", u->host.len,
			ZSW(u->host.s));
		ret=E_BUG;
		goto error;
	}

	dst.proto = proto;
	if (proto == PROTO_UDP)
	{
		dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
		if (dst.send_sock!=0){
			ret=udp_send(&dst, msg->buf, msg->len);
		}else{
			ret=-1;
		}
	}
#ifdef USE_TCP
	else{
		/*tcp*/
		dst.id=0;
		ret=tcp_send(&dst, 0, msg->buf, msg->len);
	}
#endif

	if (ret>=0) ret=1;


error:
	return ret;
}
Exemple #21
0
int get_username_domain(struct sip_msg *msg, group_check_p gcp,
											str *username, str *domain)
{
	struct sip_uri puri;
	struct sip_uri *turi;
	struct hdr_field* h;
	struct auth_body* c = 0; /* Makes gcc happy */
	pv_value_t value;

	turi = NULL;

	switch(gcp->id) {
		case 1: /* Request-URI */
			if(parse_sip_msg_uri(msg)<0) {
				LM_ERR("failed to get Request-URI\n");
				return -1;
			}
			turi = &msg->parsed_uri;
			break;

		case 2: /* To */
			if((turi=parse_to_uri(msg))==NULL) {
				LM_ERR("failed to get To URI\n");
				return -1;
			}
			break;

		case 3: /* From */
			if((turi=parse_from_uri(msg))==NULL) {
				LM_ERR("failed to get From URI\n");
				return -1;
			}
			break;

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

		case 5: /* AVP spec */
			if(pv_get_spec_value( msg, &gcp->sp, &value)!=0 
				|| value.flags&PV_VAL_NULL || value.rs.len<=0)
			{
				LM_ERR("no AVP found (error in scripts)\n");
				return -1;
			}
			if (parse_uri(value.rs.s, value.rs.len, &puri) < 0) {
				LM_ERR("failed to parse URI <%.*s>\n",value.rs.len, value.rs.s);
				return -1;
			}
			turi = &puri;
			break;
	}

	if (gcp->id != 4) {
		*username = turi->user;
		*domain = turi->host;
	} else {
		*username = c->digest.username.user;
		*domain = *(GET_REALM(&c->digest));
	}
	return 0;
}
Exemple #22
0
/**
 * @brief change the r-uri domain based on source domain and prefix
 *
 * @param msg the sip message structure
 * @param sdomain the source domain
 * @param rmode the r-uri rewrite mode
 * @param fmode the source domain fallback mode
 * @return 1 if translation is done; -1 otherwise
 */
static int pd_translate(sip_msg_t *msg, str *sdomain, int rmode, int fmode)
{
	str *d, p;
	str sdall={"*",1};
	int plen;
	
	if(msg==NULL)
	{
		LM_ERR("received null msg\n");
		return -1;
	}
	
	if(parse_sip_msg_uri(msg)<0)
	{
		LM_ERR("failed to parse the R-URI\n");
		return -1;
	}

    /* if the user part begin with the prefix, extract the code*/
	if (msg->parsed_uri.user.len<=0)
	{
		LM_DBG("user part of the message is empty\n");
		return -1;
	}   
    
	if(pdt_prefix.len>0)
	{
		if (msg->parsed_uri.user.len<=pdt_prefix.len)
		{
			LM_DBG("user part is less than prefix parameter\n");
			return -1;
		}   
		if(strncasecmp(pdt_prefix.s, msg->parsed_uri.user.s,
					pdt_prefix.len)!=0)
		{
			LM_DBG("prefix parameter did not matched\n");
			return -1;
		}
	}   
	
	p.s   = msg->parsed_uri.user.s + pdt_prefix.len;
	p.len = msg->parsed_uri.user.len - pdt_prefix.len;

again:
	lock_get( pdt_lock );
	if (pdt_reload_flag) {
		lock_release( pdt_lock );
		sleep_us(5);
		goto again;
	}
	pdt_tree_refcnt++;
	lock_release( pdt_lock );


	if((d=pdt_get_domain(*_ptree, sdomain, &p, &plen))==NULL)
	{
		plen = 0;
		if((fmode==0) || (d=pdt_get_domain(*_ptree, &sdall, &p, &plen))==NULL)
		{
			LM_INFO("no prefix PDT prefix matched [%.*s]\n", p.len, p.s);
			goto error;
		}
	}

	
	/* update the new uri */
	if(update_new_uri(msg, plen, d, rmode)<0)
	{
		LM_ERR("new_uri cannot be updated\n");
		goto error;
	}

	lock_get( pdt_lock );
	pdt_tree_refcnt--;
	lock_release( pdt_lock );
	return 1;

error:
	lock_get( pdt_lock );
	pdt_tree_refcnt--;
	lock_release( pdt_lock );
	return -1;
}
Exemple #23
0
/*
 * determines the permission of the call
 * return values:
 * -1:	deny
 * 1:	allow
 */
static int check_routing(struct sip_msg* msg, int idx)
{
	struct hdr_field *from;
	int len, q;
	static char from_str[EXPRESSION_LENGTH+1];
	static char ruri_str[EXPRESSION_LENGTH+1];
	char* uri_str;
	str branch;
	int br_idx;

	/* turn off control, allow any routing */
	if ((!allow[idx].rules) && (!deny[idx].rules)) {
		LM_DBG("no rules => allow any routing\n");
		return 1;
	}

	/* looking for FROM HF */
	if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) {
		LM_ERR("failed to parse message\n");
		return -1;
	}

	if (!msg->from) {
		LM_ERR("FROM header field not found\n");
		return -1;
	}

	/* we must call parse_from_header explicitly */
	if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) {
		LM_ERR("failed to parse From body\n");
		return -1;
	}

	from = msg->from;
	len = ((struct to_body*)from->parsed)->uri.len;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("From header field is too long: %d chars\n", len);
		return -1;
	}
	strncpy(from_str, ((struct to_body*)from->parsed)->uri.s, len);
	from_str[len] = '\0';

	/* looking for request URI */
	if (parse_sip_msg_uri(msg) < 0) {
		LM_ERR("uri parsing failed\n");
		return -1;
	}

	len = msg->parsed_uri.user.len + msg->parsed_uri.host.len + 5;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("Request URI is too long: %d chars\n", len);
		return -1;
	}

	strcpy(ruri_str, "sip:");
	memcpy(ruri_str + 4, msg->parsed_uri.user.s, msg->parsed_uri.user.len);
	ruri_str[msg->parsed_uri.user.len + 4] = '@';
	memcpy(ruri_str + msg->parsed_uri.user.len + 5, msg->parsed_uri.host.s, msg->parsed_uri.host.len);
	ruri_str[len] = '\0';

	LM_DBG("looking for From: %s Request-URI: %s\n", from_str, ruri_str);
	/* rule exists in allow file */
	if (search_rule(allow[idx].rules, from_str, ruri_str)) {
		if (check_all_branches) goto check_branches;
		LM_DBG("allow rule found => routing is allowed\n");
		return 1;
	}

	/* rule exists in deny file */
	if (search_rule(deny[idx].rules, from_str, ruri_str)) {
		LM_DBG("deny rule found => routing is denied\n");
		return -1;
	}

	if (!check_all_branches) {
		LM_DBG("neither allow nor deny rule found => routing is allowed\n");
		return 1;
	}

check_branches:
	for( br_idx=0 ; (branch.s=get_branch(br_idx,&branch.len,&q,0,0,0,0,0,0,0))!=0 ;
			br_idx++ ) {
		uri_str = get_plain_uri(&branch);
		if (!uri_str) {
			LM_ERR("failed to extract plain URI\n");
			return -1;
		}
		LM_DBG("looking for From: %s Branch: %s\n", from_str, uri_str);

		if (search_rule(allow[idx].rules, from_str, uri_str)) {
			continue;
		}

		if (search_rule(deny[idx].rules, from_str, uri_str)) {
			LM_DBG("deny rule found for one of branches => routing"
					"is denied\n");
			return -1;
		}
	}

	LM_DBG("check of branches passed => routing is allowed\n");
	return 1;
}
Exemple #24
0
static int assemble_msg(struct sip_msg* msg, struct tw_info *twi)
{
	static char     id_buf[IDBUF_LEN];
	static char     route_buffer[ROUTE_BUFFER_MAX];
	static char     append_buf[APPEND_BUFFER_MAX];
	static char     cmd_buf[CMD_BUFFER_MAX];
	static str      empty_param = {".",1};
	unsigned int      hash_index, label;
	contact_body_t*   cb=0;
	contact_t*        c=0;
	name_addr_t       na;
	rr_t*             record_route;
	struct hdr_field* p_hdr;
	param_hooks_t     hooks;
	int               l;
	char*             s, fproxy_lr;
	str               route, next_hop, append, tmp_s, body, str_uri;

	if(msg->first_line.type != SIP_REQUEST){
		LM_ERR("called for something else then a SIP request\n");
		goto error;
	}

	/* parse all -- we will need every header field for a UAS */
	if ( parse_headers(msg, HDR_EOH_F, 0)==-1) {
		LM_ERR("parse_headers failed\n");
		goto error;
	}

	/* find index and hash; (the transaction can be safely used due 
	 * to refcounting till script completes) */
	if( t_get_trans_ident(msg,&hash_index,&label) == -1 ) {
		LM_ERR("t_get_trans_ident failed\n");
		goto error;
	}

	 /* parse from header */
	if (msg->from->parsed==0 && parse_from_header(msg)<0 ) {
		LM_ERR("failed to parse <From:> header\n");
		goto error;
	}

	/* parse the RURI (doesn't make any malloc) */
	msg->parsed_uri_ok = 0; /* force parsing */
	if (parse_sip_msg_uri(msg)<0) {
		LM_ERR("uri has not been parsed\n");
		goto error;
	}

	/* parse contact header */
	str_uri.s = 0;
	str_uri.len = 0;
	if(msg->contact) {
		if (msg->contact->parsed==0 && parse_contact(msg->contact)<0) {
			LM_ERR("failed to parse <Contact:> header\n");
			goto error;
		}
		cb = (contact_body_t*)msg->contact->parsed;
		if(cb && (c=cb->contacts)) {
			str_uri = c->uri;
			if (find_not_quoted(&str_uri,'<')) {
				parse_nameaddr(&str_uri,&na);
				str_uri = na.uri;
			}
		}
	}

	/* str_uri is taken from caller's contact or from header
	 * for backwards compatibility with pre-3261 (from is already parsed)*/
	if(!str_uri.len || !str_uri.s)
		str_uri = get_from(msg)->uri;

	/* parse Record-Route headers */
	route.s = s = route_buffer; route.len = 0;
	fproxy_lr = 0;
	next_hop = empty_param;

	p_hdr = msg->record_route;
	if(p_hdr) {
		if (p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ) {
			LM_ERR("failed to parse 'Record-Route:' header\n");
			goto error;
		}
		record_route = (rr_t*)p_hdr->parsed;
	} else {
		record_route = 0;
	}

	if( record_route ) {
		if ( (tmp_s.s=find_not_quoted(&record_route->nameaddr.uri,';'))!=0 &&
		tmp_s.s+1!=record_route->nameaddr.uri.s+
		record_route->nameaddr.uri.len) {
			/* Parse all parameters */
			tmp_s.len = record_route->nameaddr.uri.len - (tmp_s.s-
				record_route->nameaddr.uri.s);
			if (parse_params( &tmp_s, CLASS_URI, &hooks, 
			&record_route->params) < 0) {
				LM_ERR("failed to parse record route uri params\n");
				goto error;
			}
			fproxy_lr = (hooks.uri.lr != 0);
			LM_DBG("record_route->nameaddr.uri: %.*s\n",
				record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);
			if(fproxy_lr){
				LM_DBG("first proxy has loose routing\n");
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}
		for(p_hdr = p_hdr->next;p_hdr;p_hdr = p_hdr->next) {
			/* filter out non-RR hdr and empty hdrs */
			if( (p_hdr->type!=HDR_RECORDROUTE_T) || p_hdr->body.len==0)
				continue;

			if(p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ){
				LM_ERR("failed to parse <Record-route:> header\n");
				goto error;
			}
			for(record_route=p_hdr->parsed; record_route;
				record_route=record_route->next){
				LM_DBG("record_route->nameaddr.uri: <%.*s>\n",
					record_route->nameaddr.uri.len,
					record_route->nameaddr.uri.s);
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}

		if(!fproxy_lr){
			copy_route(s,route.len,str_uri.s,str_uri.len);
			str_uri = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		} else {
			next_hop = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		}
	}

	LM_DBG("calculated route: %.*s\n",route.len,route.len ? route.s : "");
	LM_DBG("next r-uri: %.*s\n",str_uri.len,str_uri.len ? str_uri.s : "");

	if ( REQ_LINE(msg).method_value==METHOD_INVITE || 
	(twi->append && twi->append->add_body) ) {
		/* get body */
		if( (body.s = get_body(msg)) == 0 ){
			LM_ERR("get_body failed\n");
			goto error;
		}
		body.len = msg->len - (body.s - msg->buf);
	} else {
		body = empty_param;
	}

	/* flags & additional headers */
	append.s = s = append_buf;
	if (sizeof(flag_t)*2+12+1 >= APPEND_BUFFER_MAX) {
		LM_ERR("buffer overflow while copying flags\n");
		goto error;
	}
	append_str(s,"P-MsgFlags: ",12);
	l = APPEND_BUFFER_MAX - (12+1); /* include trailing `\n'*/

	if (int2reverse_hex(&s, &l, (int)msg->msg_flags) == -1) {
		LM_ERR("buffer overflow while copying optional header\n");
		goto error;
	}
	append_chr(s,'\n');

	if ( twi->append && ((s=append2buf( s, APPEND_BUFFER_MAX-(s-append.s), msg,
	twi->append->elems))==0) )
		goto error;

	/* body separator */
	append_chr(s,'.');
	append.len = s-append.s;

	eol_line(1).s = s = cmd_buf;
	if(twi->action.len+12 >= CMD_BUFFER_MAX){
		LM_ERR("buffer overflow while copying command name\n");
		goto error;
	}
	append_str(s,"sip_request.",12);
	append_str(s,twi->action.s,twi->action.len);
	eol_line(1).len = s-eol_line(1).s;

	eol_line(2)=REQ_LINE(msg).method;     /* method type */
	eol_line(3)=msg->parsed_uri.user;     /* user from r-uri */
	eol_line(4)=msg->parsed_uri.host;     /* domain */

	eol_line(5)=msg->rcv.bind_address->address_str; /* dst ip */

	eol_line(6)=msg->rcv.dst_port==SIP_PORT ?
			empty_param : msg->rcv.bind_address->port_no_str; /* port */

	/* r_uri ('Contact:' for next requests) */
	eol_line(7)=*GET_RURI(msg);

	/* r_uri for subsequent requests */
	eol_line(8)=str_uri.len?str_uri:empty_param;

	eol_line(9)=get_from(msg)->body;		/* from */
	eol_line(10)=msg->to->body;			/* to */
	eol_line(11)=msg->callid->body;		/* callid */
	eol_line(12)=get_from(msg)->tag_value;	/* from tag */
	eol_line(13)=get_to(msg)->tag_value;	/* to tag */
	eol_line(14)=get_cseq(msg)->number;	/* cseq number */

	eol_line(15).s=id_buf;       /* hash:label */
	s = int2str(hash_index, &l);
	if (l+1>=IDBUF_LEN) {
		LM_ERR("too big hash\n");
		goto error;
	}
	memcpy(id_buf, s, l);
	id_buf[l]=':';
	eol_line(15).len=l+1;
	s = int2str(label, &l);
	if (l+1+eol_line(15).len>=IDBUF_LEN) {
		LM_ERR("too big label\n");
		goto error;
	}
	memcpy(id_buf+eol_line(15).len, s, l);
	eol_line(15).len+=l;

	eol_line(16) = route.len ? route : empty_param;
	eol_line(17) = next_hop;
	eol_line(18) = append;
	eol_line(19) = body;

	/* success */
	return 1;
error:
	/* 0 would lead to immediate script exit -- -1 returns
	 * with 'false' to script processing */
	return -1;
}
Exemple #25
0
/* returns: 0/1 (false/true) or -1 on error, -127 EXPR_DROP */
static int eval_elem(struct expr* e, struct sip_msg* msg, pv_value_t *val)
{

	struct sip_uri uri;
	int ret;
	int retl;
	int retr;
	int ival;
	pv_value_t lval;
	pv_value_t rval;
	char *p;
	
	ret=E_BUG;
	if (e->type!=ELEM_T){
		LM_CRIT("invalid type\n");
		goto error;
	}
	
	if(val) memset(val, 0, sizeof(pv_value_t));

	switch(e->left.type){
		case METHOD_O:
				ret=comp_strval(msg, e->op, &msg->first_line.u.request.method,
						&e->right);
				break;
		case URI_O:
				if(msg->new_uri.s){
					if (e->right.type==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strval(msg, e->op, &msg->new_uri, &e->right);
					}
				}else{
					if (e->right.type==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strval(msg, e->op,
								&msg->first_line.u.request.uri,
								&e->right);
					}
				}
				break;
		case FROM_URI_O:
				if (parse_from_header(msg)<0){
					LM_ERR("bad or missing From: header\n");
					goto error;
				}
				if (e->right.type==MYSELF_ST){
					if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len,
									&uri) < 0){
						LM_ERR("bad uri in From:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strval(msg, e->op, &get_from(msg)->uri,
							&e->right);
				}
				break;
		case TO_URI_O:
				if ((msg->to==0) && ((parse_headers(msg, HDR_TO_F, 0)==-1) ||
							(msg->to==0))){
					LM_ERR("bad or missing To: header\n");
					goto error;
				}
				/* to content is parsed automatically */
				if (e->right.type==MYSELF_ST){
					if (parse_uri(get_to(msg)->uri.s, get_to(msg)->uri.len,
									&uri) < 0){
						LM_ERR("bad uri in To:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strval(msg, e->op, &get_to(msg)->uri,
										&e->right);
				}
				break;
		case SRCIP_O:
				ret=comp_ip(msg, e->op, &msg->rcv.src_ip, &e->right);
				break;
		case DSTIP_O:
				ret=comp_ip(msg, e->op, &msg->rcv.dst_ip, &e->right);
				break;
		case NUMBER_O:
				ret=!(!e->right.v.n); /* !! to transform it in {0,1} */
				break;
		case ACTION_O:
				ret=run_action_list( (struct action*)e->right.v.data, msg);
				if(val)
				{
					val->flags = PV_TYPE_INT|PV_VAL_INT;
					val->ri = ret;
				}
				if (ret<=0) ret=(ret==0)?EXPR_DROP:0;
				else ret=1;
				return ret;
		case EXPR_O:
				retl = retr = 0;
				memset(&lval, 0, sizeof(pv_value_t));
				memset(&rval, 0, sizeof(pv_value_t));
				if(e->left.v.data)
					retl=eval_expr((struct expr*)e->left.v.data,msg,&lval);
				if(lval.flags == PV_VAL_NONE)
				{
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 0;
				}
				if(e->op == BNOT_OP)
				{
					if(lval.flags&PV_VAL_INT)
					{
						if(val!=NULL)
						{
							val->flags = PV_TYPE_INT|PV_VAL_INT;
							val->ri = ~lval.ri;
						}
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return (val->ri)?1:0;
					}
					LM_ERR("binary NOT on non-numeric value\n");
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 0;
				}
				if(e->right.v.data)
					retr=eval_expr((struct expr*)e->right.v.data,msg,&rval);
			
				if(lval.flags&PV_TYPE_INT)
				{
					if(!(rval.flags&PV_VAL_INT))
					{
						LM_ERR("invalid numeric operands\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					if(val!=NULL)
						val->flags = PV_TYPE_INT|PV_VAL_INT;

					ival = 0;
					switch(e->op) {
						case PLUS_OP:
							ival = lval.ri + rval.ri;
							break;
						case MINUS_OP:
							ival = lval.ri - rval.ri;
							break;
						case DIV_OP:
							if(rval.ri==0)
							{
								LM_ERR("divide by 0\n");
								pv_value_destroy(&lval);
								pv_value_destroy(&rval);
								return 0;
							} else 
								ival = lval.ri / rval.ri;
							break;
						case MULT_OP:
							ival = lval.ri * rval.ri;
							break;
						case MODULO_OP:
							if(rval.ri==0)
							{
								LM_ERR("divide by 0\n");
								pv_value_destroy(&lval);
								pv_value_destroy(&rval);
								return 0;
							} else 
								ival = lval.ri % rval.ri;
							break;
						case BAND_OP:
							ival = lval.ri & rval.ri;
							break;
						case BOR_OP:
							ival = lval.ri | rval.ri;
							break;
						case BXOR_OP:
							ival = lval.ri ^ rval.ri;
							break;
						default:
							LM_ERR("invalid int op %d\n", e->op);
								val->ri = 0;
							pv_value_destroy(&lval);
							pv_value_destroy(&rval);
							return 0;
					}
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					if(val!=NULL) val->ri = ival;
					return (ival)?1:0;
				} else {
					if(!(rval.flags&PV_VAL_STR))
					{
						LM_ERR("invalid string operands\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					if(e->op != PLUS_OP)
					{
						LM_ERR("invalid string operator %d\n", e->op);
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					if(val==NULL)
					{
						ret = (lval.rs.len>0 || rval.rs.len>0);
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return ret;
					}
					val->rs.s=(char*)pkg_malloc((lval.rs.len+rval.rs.len+1)
							*sizeof(char));
					if(val->rs.s==0)
					{
						LM_ERR("no more memory\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					val->flags = PV_VAL_PKG|PV_VAL_STR;
					memcpy(val->rs.s, lval.rs.s, lval.rs.len);
					memcpy(val->rs.s+lval.rs.len, rval.rs.s, rval.rs.len);
					val->rs.len = lval.rs.len + rval.rs.len;
					val->rs.s[val->rs.len] = '\0';
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 1;
				}
				break;
		case SRCPORT_O:
				ret=comp_no(msg->rcv.src_port, 
					e->right.v.data, /* e.g., 5060 */
					e->op, /* e.g. == */
					e->right.type /* 5060 is number */);
				break;
		case DSTPORT_O:
				ret=comp_no(msg->rcv.dst_port, e->right.v.data, e->op, 
							e->right.type);
				break;
		case PROTO_O:
				ret=comp_no(msg->rcv.proto, e->right.v.data, e->op,
						e->right.type);
				break;
		case AF_O:
				ret=comp_no(msg->rcv.src_ip.af, e->right.v.data, e->op,
						e->right.type);
				break;
		case RETCODE_O:
				ret=comp_no(return_code, e->right.v.data, e->op,
						e->right.type);
				break;
		case MSGLEN_O:
				ret=comp_no(msg->len, e->right.v.data, e->op,
						e->right.type);
				break;
		case STRINGV_O:
				if(val) {
					val->flags = PV_VAL_STR;
					val->rs = e->left.v.s;
				}
				/* optimization for no dup ?!?! */
				return (e->left.v.s.len>0)?1:0;
		case NUMBERV_O:
				if(val) {
					val->flags = PV_TYPE_INT|PV_VAL_INT;
					val->ri = e->left.v.n;
				}
				ret=!(!e->left.v.n); /* !! to transform it in {0,1} */
				return ret;
		case SCRIPTVAR_O:
				if(e->op==NO_OP)
				{
					memset(&rval, 0, sizeof(pv_value_t));
					if(pv_get_spec_value(msg, e->right.v.spec, &rval)==0)
					{
						if(rval.flags==PV_VAL_NONE || (rval.flags&PV_VAL_NULL)
								|| (rval.flags&PV_VAL_EMPTY)
								|| ((rval.flags&PV_TYPE_INT)&&rval.ri==0))
						{
							pv_value_destroy(&rval);
							return 0;
						}
						if(rval.flags&PV_TYPE_INT)
						{
							pv_value_destroy(&rval);
							return 1;
						}
						if(rval.rs.len!=0)
						{
							pv_value_destroy(&rval);
							return 1;
						}
						pv_value_destroy(&rval);
					}
					return 0;
				}
				if(e->op==VALUE_OP)
				{
					if(pv_get_spec_value(msg, e->left.v.spec, &lval)==0)
					{
						if(val!=NULL)
							memcpy(val, &lval, sizeof(pv_value_t));
						if(lval.flags&PV_VAL_STR)
						{
							if(!((lval.flags&PV_VAL_PKG) 
									|| (lval.flags&PV_VAL_SHM)))
							{
								if(val!=NULL)
								{
									/* do pkg duplicate */
									p = (char*)pkg_malloc((val->rs.len+1)
											*sizeof(char));
									if(p==0)
									{
										LM_ERR("no more pkg memory\n");
										memset(val, 0, sizeof(pv_value_t));
										return 0;
									}
									memcpy(p, val->rs.s, val->rs.len);
									p[val->rs.len] = 0;
									val->rs.s = p;
									val->flags|= PV_VAL_PKG;
								}
							}
							return 1;
						}
						if(lval.flags==PV_VAL_NONE 
								|| (lval.flags & PV_VAL_NULL)
								|| (lval.flags & PV_VAL_EMPTY))
							return 0;
						if(lval.flags&PV_TYPE_INT)
							return (lval.ri!=0);
						else
							return (lval.rs.len>0);
					}
					return 0;
				}

				ret=comp_scriptvar(msg, e->op, &e->left, &e->right);
				break;
		default:
				LM_CRIT("invalid operand %d\n", e->left.type);
	}
	if(val)
	{
		val->flags = PV_TYPE_INT|PV_VAL_INT;
		val->ri = ret;
	}
	return ret;
error:
	if(val)
	{
		val->flags = PV_TYPE_INT|PV_VAL_INT;
		val->ri = -1;
	}
	return -1;
}
Exemple #26
0
/* change the r-uri if it is a PSTN format */
static int prefix2domain(struct sip_msg* msg, int mode, int sd_en)
{
	str *d, p, all={"*",1};
	int plen;
	struct sip_uri uri;

	if(msg==NULL)
	{
		LM_ERR("received null msg\n");
		return -1;
	}

	/* parse the uri, if not yet */
	if(msg->parsed_uri_ok==0)
		if(parse_sip_msg_uri(msg)<0)
		{
			LM_ERR("failed to parse the R-URI\n");
			return -1;
		}

    /* if the user part begin with the prefix for PSTN users, extract the code*/
	if (msg->parsed_uri.user.len<=0)
	{
		LM_DBG("user part of the message is empty\n");
		return -1;
	}

	if(prefix.len>0)
	{
		if (msg->parsed_uri.user.len<=prefix.len)
		{
			LM_DBG("user part is less than prefix\n");
			return -1;
		}
		if(strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0)
		{
			LM_DBG("PSTN prefix did not matched\n");
			return -1;
		}
	}

	if(prefix.len>0 && prefix.len < msg->parsed_uri.user.len
			&& strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0)
	{
		LM_DBG("PSTN prefix did not matched\n");
		return -1;

	}

	p.s   = msg->parsed_uri.user.s + prefix.len;
	p.len = msg->parsed_uri.user.len - prefix.len;

	lock_start_read( pdt_lock );

	if(sd_en==2)
	{
		/* take the domain from  FROM uri as sdomain */
		if(parse_from_header(msg)<0 ||  msg->from == NULL
				|| get_from(msg)==NULL)
		{
			LM_ERR("cannot parse FROM header\n");
			goto error;
		}

		memset(&uri, 0, sizeof(struct sip_uri));
		if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0)
		{
			LM_ERR("failed to parse From uri\n");
			goto error;
		}

		/* find the domain that corresponds to this prefix */
		plen = 0;
		if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL)
		{
			plen = 0;
			if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL)
			{
				LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
				goto error;
			}
		}
	} else if(sd_en==1) {
		/* take the domain from  FROM uri as sdomain */
		if(parse_from_header(msg)<0 ||  msg->from == NULL
				|| get_from(msg)==NULL)
		{
			LM_ERR("ERROR cannot parse FROM header\n");
			goto error;
		}

		memset(&uri, 0, sizeof(struct sip_uri));
		if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0)
		{
			LM_ERR("failed to parse From uri\n");
			goto error;
		}

		/* find the domain that corresponds to this prefix */
		plen = 0;
		if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL)
		{
			LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
			goto error;
		}
	} else {
		/* find the domain that corresponds to this prefix */
		plen = 0;
		if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL)
		{
			LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
			goto error;
		}
	}

	/* update the new uri */
	if(update_new_uri(msg, plen, d, mode)<0)
	{
		LM_ERR("new_uri cannot be updated\n");
		goto error;
	}

	lock_stop_read( pdt_lock );
	return 1;

error:
	lock_stop_read( pdt_lock );
	return -1;
}
Exemple #27
0
int i_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
	char *user_s;
	int user_len, i, j;
	char name[MAX_DOMAIN_SIZE];
	char apex[MAX_COMPONENT_SIZE + 1];
	char separator[MAX_COMPONENT_SIZE + 1];
	int sdl = 0;    /* subdomain location: infrastructure enum offset */
	int cc_len;
	struct rdata* head;

	char string[MAX_NUM_LEN];

	str *suffix, *service;

	suffix = (str*)_suffix;
	service = (str*)_service;

	if (parse_sip_msg_uri(_msg) < 0) {
		LM_ERR("Parsing of R-URI failed\n");
		return -1;
	}

	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
		LM_ERR("R-URI user is not an E164 number\n");
		return -1;
	}

	user_s = _msg->parsed_uri.user.s;
	user_len = _msg->parsed_uri.user.len;

	/* make sure we don't run out of space in strings */
	if (( 2*user_len + MAX_COMPONENT_SIZE + MAX_COMPONENT_SIZE + 4) > MAX_DOMAIN_SIZE) {
		LM_ERR("Strings too long\n");
		return -1;
	}
	if ( i_branchlabel.len > MAX_COMPONENT_SIZE ) {
		LM_ERR("i_branchlabel too long\n");
		return -1;
	}
	if ( suffix->len > MAX_COMPONENT_SIZE ) {
		LM_ERR("Suffix too long\n");
		return -1;
	}


	memcpy(&(string[0]), user_s, user_len);
	string[user_len] = (char)0;

	/* Set up parameters as for user-enum */
	memcpy(apex,  suffix->s , suffix->len);
	apex[suffix->len] = (char)0;
	sdl = 0;		/* where to insert i-enum separator */
	separator[0] = 0;	/* don't insert anything */

	cc_len = cclen(string + 1);

	if (!strncasecmp(i_bl_alg.s,"ebl",i_bl_alg.len)) {
		sdl = cc_len; /* default */

		j = 0;
		memcpy(name, i_branchlabel.s, i_branchlabel.len);
		j += i_branchlabel.len;
		name[j++] = '.';

		for (i = cc_len ; i > 0; i--) {
			name[j++] = user_s[i];
			name[j++] = '.';
		}
		memcpy(name + j, suffix->s, suffix->len + 1);

		LM_DBG("Looking for EBL record for %s.\n", name); 
		head = get_record(name, T_EBL, RES_ONLY_TYPE);
		if (head == 0) {
			LM_DBG("No EBL found for %s. Defaulting to user ENUM.\n",name);
		} else {
		    	struct ebl_rdata* ebl;
			ebl = (struct ebl_rdata *) head->rdata;

			LM_DBG("EBL record for %s is %d / %.*s / %.*s.\n",
			       name, ebl->position, (int)ebl->separator_len,
			       ebl->separator,(int)ebl->apex_len, ebl->apex);

			if ((ebl->apex_len > MAX_COMPONENT_SIZE) || (ebl->separator_len > MAX_COMPONENT_SIZE)) {
				LM_ERR("EBL strings too long\n"); 
				return -1;
			}

			if (ebl->position > 15)  {
				LM_ERR("EBL position too large (%d)\n",
				       ebl->position); 
				return -1;
			}

			sdl = ebl->position;

			memcpy(separator, ebl->separator, ebl->separator_len);
			separator[ebl->separator_len] = 0;

			memcpy(apex, ebl->apex, ebl->apex_len);
			apex[ebl->apex_len] = 0;
			free_rdata_list(head);
		}
	} else if (!strncasecmp(i_bl_alg.s,"txt",i_bl_alg.len)) {
		sdl = cc_len; /* default */
		memcpy(separator, i_branchlabel.s, i_branchlabel.len);
		separator[i_branchlabel.len] = 0;
		/* no change to apex */

		j = 0;
		memcpy(name, i_branchlabel.s, i_branchlabel.len);
		j += i_branchlabel.len;
		name[j++] = '.';

		for (i = cc_len ; i > 0; i--) {
			name[j++] = user_s[i];
			name[j++] = '.';
		}
		memcpy(name + j, suffix->s, suffix->len + 1);

		head = get_record(name, T_TXT, RES_ONLY_TYPE);
		if (head == 0) {
			LM_DBG("TXT found for %s. Defaulting to %d\n",
			       name, cc_len);
		} else {
			sdl = atoi(((struct txt_rdata*)head->rdata)->txt[0].cstr);
			LM_DBG("TXT record for %s is %d.\n", name, sdl);

			if ((sdl < 0) || (sdl > 10)) {
				LM_ERR("Sdl %d out of bounds. Set back to cc_len.\n", sdl);
				sdl = cc_len;
			}
			free_rdata_list(head);
		}
	} else {	/* defaults to CC */
		sdl = cc_len;
		memcpy(separator, i_branchlabel.s, i_branchlabel.len);
		separator[i_branchlabel.len] = 0;
		/* no change to apex */
	}

	j = 0;
	sdl++; /* to avoid comparing i to (sdl+1) */
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
		if (separator[0] && (i == sdl)) { /* insert the I-ENUM separator here? */
			strcpy(name + j, separator);  /* we've checked string sizes. */
			j += strlen(separator);
			name[j++] = '.';
		}
	}

	memcpy(name + j, apex, strlen(apex)+1);

	return do_query(_msg, string, name, service);
}
Exemple #28
0
int rls_handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain)
{
	subs_t subs;
	pres_ev_t* event = NULL;
	int err_ret = -1;
	int ret = to_presence_code;
	str* contact = NULL;
	xmlDocPtr doc = NULL;
	xmlNodePtr service_node = NULL;
	unsigned int hash_code=0;
	int to_tag_gen = 0;
	event_t* parsed_event;
	param_t* ev_param = NULL;
	str reason;
	int rt;
	str rlsubs_did = {0, 0};

	memset(&subs, 0, sizeof(subs_t));

	/** sanity checks - parse all headers */
	if (parse_headers(msg, HDR_EOH_F, 0)<-1)
	{
		LM_ERR("failed parsing all headers\n");
		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
		{
			LM_ERR("while sending 400 reply\n");
			return -1;
		}
		return 0;
	}
	/* check for To and From headesr */
	if(parse_to_uri(msg)<0 || parse_from_uri(msg)<0)
	{
		LM_ERR("failed to find To or From headers\n");
		if (slb.freply(msg, 400, &pu_400_rpl) < 0)
		{
			LM_ERR("while sending 400 reply\n");
			return -1;
		}
		return 0;
	}
	if(get_from(msg)->tag_value.s ==NULL || get_from(msg)->tag_value.len==0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find callid header\n");
		return -1;
	}
	if(parse_sip_msg_uri(msg)<0)
	{
		LM_ERR("failed parsing Request URI\n");
		return -1;
	}

	/* check for header 'Support: eventlist' */
	if(msg->supported==NULL)
	{
		LM_DBG("supported header not found - not for rls\n");
		goto forpresence;
	}

	if(parse_supported(msg)<0)
	{
		LM_ERR("failed to parse supported headers\n");
		return -1;
	}

	if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST))
	{
		LM_DBG("No support for 'eventlist' - not for rls\n");
		goto forpresence;
	}

	/* inspecting the Event header field */
	if(msg->event && msg->event->body.len > 0)
	{
		if (!msg->event->parsed && (parse_event(msg->event) < 0))
		{
			LM_ERR("cannot parse Event header\n");
			goto error;
		}
		if(! ( ((event_t*)msg->event->parsed)->type & rls_events) )
		{	
			goto forpresence;
		}
	} else {
		goto bad_event;
	}

	/* search event in the list */
	parsed_event = (event_t*)msg->event->parsed;
	event = pres_search_event(parsed_event);
	if(event==NULL)
	{
		goto bad_event;
	}
	subs.event= event;

	/* extract the id if any*/
	ev_param= parsed_event->params.list;
	while(ev_param)
	{
		if(ev_param->name.len==2 && strncmp(ev_param->name.s, "id", 2)==0)
		{
			subs.event_id = ev_param->body;
			break;
		}
		ev_param= ev_param->next;
	}

	/* extract dialog information from message headers */
	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
				&to_tag_gen, rls_server_address,
				watcher_user, watcher_domain)<0)
	{
		LM_ERR("bad subscribe request\n");
		goto error;
	}

	hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size);
	if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0)
	{
		LM_ERR("cannot build rls subs did\n");
		goto error;
	}
	subs.updated = core_hash(&rlsubs_did, NULL, 0) %
		(waitn_time * rls_notifier_poll_rate * rls_notifier_processes);
	
	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
	{ /* initial Subscribe */
		/*verify if Request URI represents a list by asking xcap server*/	
		if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
					&subs.pres_uri)<0)
		{
			LM_ERR("while constructing uri from user and domain\n");
			goto error;
		}
		if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user,
					&subs.watcher_domain, &service_node, &doc)<0)
		{
			LM_ERR("while attepmting to get a resource list\n");
			goto error;
		}
		if(doc==NULL)
		{
			/* if not for RLS, pass it to presence serivce */
			LM_DBG("list not found - searched for uri <%.*s>\n",
					subs.pres_uri.len, subs.pres_uri.s);
			goto forpresence;
		}

		/* if correct reply with 200 OK */
		if(reply_200(msg, &subs.local_contact, subs.expires)<0)
			goto error;

		subs.local_cseq = 0;

		if(subs.expires != 0)
		{
			subs.version = 1;
			if (dbmode==RLS_DB_ONLY)
			{
				rt=insert_rlsdb( &subs );
			}
			else
			{
				rt=pres_insert_shtable(rls_table, hash_code, &subs);
			}
			if (rt<0)
			{
				LM_ERR("while adding new subscription\n");
				goto error;
			}
		}
	} else {
		/* search if a stored dialog */
		if ( dbmode == RLS_DB_ONLY )
		{
			if (rls_dbf.start_transaction)
			{
				if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0)
				{
					LM_ERR("in start_transaction\n");
					goto error;
				}
			}

			rt = get_dialog_subscribe_rlsdb(&subs);

			if (rt <= 0)
			{
				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
						subs.watcher_user.len, subs.watcher_user.s,
						subs.watcher_domain.len, subs.watcher_domain.s);

				if (rls_dbf.end_transaction)
				{
					if (rls_dbf.end_transaction(rls_db) < 0)
					{
						LM_ERR("in end_transaction\n");
						goto error;
					}
				}

				goto forpresence;
			}
			else if(rt>=400)
			{
				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
		
				if (slb.freply(msg, 400, &reason) < 0)
				{
					LM_ERR("while sending reply\n");
					goto error;
				}

				if (rls_dbf.end_transaction)
				{
					if (rls_dbf.end_transaction(rls_db) < 0)
					{
						LM_ERR("in end_transaction\n");
						goto error;
					}
				}

				ret = 0;
				goto stop;
			}

			/* if correct reply with 200 OK */
			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
				goto error;

			if (update_dialog_subscribe_rlsdb(&subs) < 0)
			{
				LM_ERR("while updating resource list subscription\n");
				goto error;
			}

			if (rls_dbf.end_transaction)
			{
				if (rls_dbf.end_transaction(rls_db) < 0)
				{
					LM_ERR("in end_transaction\n");
					goto error;
				}
			}
		}
		else
		{
			lock_get(&rls_table[hash_code].lock);
			if(pres_search_shtable(rls_table, subs.callid,
					subs.to_tag, subs.from_tag, hash_code)==NULL)
			{
				lock_release(&rls_table[hash_code].lock);
				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
						subs.watcher_user.len, subs.watcher_user.s,
						subs.watcher_domain.len, subs.watcher_domain.s);
				goto forpresence;
			}
			lock_release(&rls_table[hash_code].lock);

			/* if correct reply with 200 OK */
			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
				goto error;

			rt = update_rlsubs(&subs, hash_code);

			if(rt<0)
			{
				LM_ERR("while updating resource list subscription\n");
				goto error;
			}
	
			if(rt>=400)
			{
				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
		
				if (slb.freply(msg, 400, &reason) < 0)
				{
					LM_ERR("while sending reply\n");
					goto error;
				}
				ret = 0;
				goto stop;
			}
		}	
		if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user,
					&subs.watcher_domain, &service_node, &doc)<0)
		{
			LM_ERR("failed getting resource list\n");
			goto error;
		}
		if(doc==NULL)
		{
			/* warning: no document returned?!?! */
			LM_WARN("no document returned for uri <%.*s>\n",
					subs.pres_uri.len, subs.pres_uri.s);
			goto done;
		}
	}

	if (dbmode != RLS_DB_ONLY)
	{
		/* sending notify with full state */
		if(send_full_notify(&subs, service_node, &subs.pres_uri, hash_code)<0)
		{
			LM_ERR("failed sending full state notify\n");
			goto error;
		}
	}

	/* send subscribe requests for all in the list */
	if(resource_subscriptions(&subs, service_node)< 0)
	{
		LM_ERR("failed sending subscribe requests to resources in list\n");
		goto error;
	}

	if (dbmode !=RLS_DB_ONLY)
		remove_expired_rlsubs(&subs, hash_code);

done:
	ret = 1;
stop:
forpresence:
	if(contact!=NULL)
	{	
		if(contact->s!=NULL)
			pkg_free(contact->s);
		pkg_free(contact);
	}

	if(subs.pres_uri.s!=NULL)
		pkg_free(subs.pres_uri.s);
	if(subs.record_route.s!=NULL)
		pkg_free(subs.record_route.s);
	if(doc!=NULL)
		xmlFreeDoc(doc);
	if (rlsubs_did.s != NULL)
		pkg_free(rlsubs_did.s);
	return ret;

bad_event:
	err_ret = 0;
	if(reply_489(msg)<0)
	{
		LM_ERR("failed sending 489 reply\n");
		err_ret = -1;
	}

error:
	LM_ERR("occured in rls_handle_subscribe\n");

	if(contact!=NULL)
	{	
		if(contact->s!=NULL)
			pkg_free(contact->s);
		pkg_free(contact);
	}
	if(subs.pres_uri.s!=NULL)
		pkg_free(subs.pres_uri.s);

	if(subs.record_route.s!=NULL)
		pkg_free(subs.record_route.s);

	if(doc!=NULL)
		xmlFreeDoc(doc);

	if (rlsubs_did.s != NULL)
		pkg_free(rlsubs_did.s);

	if (rls_dbf.abort_transaction)
	{
		if (rls_dbf.abort_transaction(rls_db) < 0)
			LM_ERR("in abort_transaction\n");
	}
	
	return err_ret;
}
Exemple #29
0
/*
 * Check from AAA server 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 aaa_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain;
	dig_cred_t* cred = 0;
	int hf_type;
	uint32_t service;

	aaa_message *send = NULL, *received = NULL;

	struct hdr_field* h;
	struct sip_uri *turi;

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

	hf_type = (int)(long)_hf;

	turi = 0;

	switch(hf_type) {
		case 1: /* Request-URI */
			if(parse_sip_msg_uri(_m)<0) {
				LM_ERR("failed to get Request-URI\n");
				return -1;
			}
			turi = &_m->parsed_uri;
			break;

		case 2: /* To */
			if((turi=parse_to_uri(_m))==NULL) {
				LM_ERR("failed to get To URI\n");
				return -1;
			}
			break;

		case 3: /* From */
			if((turi=parse_from_uri(_m))==NULL) {
				LM_ERR("failed to get From URI\n");
				return -1;
			}
			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) {
		user = turi->user;
		domain = turi->host;
	} else {
		user = cred->username.user;
		domain = *GET_REALM(cred);
	}

	if (user.s == NULL || user.len == 0) {
		LM_DBG("no username part\n");
		return -1;
	}

	if (use_domain) {
		user_name.len = user.len + domain.len + 1;
		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);
		user_name.s[user.len] = '@';
		memcpy(user_name.s + user.len + 1, domain.s, domain.len);
	} else {
		user_name = user;
	}

	if ((send = proto.create_aaa_message(conn, AAA_AUTH)) == NULL) {
		LM_ERR("failed to create new aaa message for auth \n");
		return -1;
	}

	if (proto.avp_add(conn, send, &attrs[A_USER_NAME], user_name.s, user_name.len, 0)) {
		proto.destroy_aaa_message(conn, send);
		if (use_domain) pkg_free(user_name.s);
		return -7;
	}

	if (use_domain) pkg_free(user_name.s);


	if (proto.avp_add(conn, send, &attrs[A_SIP_GROUP], grp->s, grp->len, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("failed to add Sip-Group attribute\n");
		return -8;
	}

	service = vals[V_GROUP_CHECK].value;

	if (proto.avp_add(conn, send, &attrs[A_SERVICE_TYPE], &service, -1, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("failed to add Service-Type attribute\n");
		return -8;
	}

	/* Add CALL-ID in Acct-Session-Id Attribute */
	if ((parse_headers(_m, HDR_CALLID_F, 0) == -1 || _m->callid == NULL) &&
		 _m->callid == NULL) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("msg parsing failed or callid not present");
		return -10;
	}

	if (proto.avp_add(conn, send, &attrs[A_ACCT_SESSION_ID], _m->callid->body.s,
	_m->callid->body.len, 0)) {
		proto.destroy_aaa_message(conn, send);
		LM_ERR("unable to add CALL-ID attribute\n");
		return -11;
	}

	if (!proto.send_aaa_request(conn, send, &received)) {
		LM_DBG("Success\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return 1;
	} else {
		LM_DBG("Failure\n");
		proto.destroy_aaa_message(conn, send);
		proto.destroy_aaa_message(conn, received);
		return -12;
	}
}
Exemple #30
0
static int pv_auth_check(sip_msg_t *msg, char *realm,
                         char *passwd, char *flags, char *checks)
{
    int vflags = 0;
    int vchecks = 0;
    str srealm  = {0, 0};
    str spasswd = {0, 0};
    int ret;
    hdr_field_t *hdr;
    sip_uri_t *uri = NULL;
    sip_uri_t *turi = NULL;
    sip_uri_t *furi = NULL;

    if(msg==NULL) {
        LM_ERR("invalid msg parameter\n");
        return AUTH_ERROR;
    }

    if ((msg->REQ_METHOD == METHOD_ACK) || (msg->REQ_METHOD == METHOD_CANCEL)) {
        return AUTH_OK;
    }

    if(realm==NULL || passwd==NULL || flags==NULL || checks==NULL) {
        LM_ERR("invalid parameters\n");
        return AUTH_ERROR;
    }

    if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
        LM_ERR("failed to get realm value\n");
        return AUTH_ERROR;
    }

    if(srealm.len==0) {
        LM_ERR("invalid realm value - empty content\n");
        return AUTH_ERROR;
    }

    if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) {
        LM_ERR("failed to get passwd value\n");
        return AUTH_ERROR;
    }

    if(spasswd.len==0) {
        LM_ERR("invalid password value - empty content\n");
        return AUTH_ERROR;
    }

    if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
        LM_ERR("invalid flags value\n");
        return AUTH_ERROR;
    }

    if (get_int_fparam(&vchecks, msg, (fparam_t*)checks) < 0) {
        LM_ERR("invalid checks value\n");
        return AUTH_ERROR;
    }
    LM_DBG("realm [%.*s] flags [%d] checks [%d]\n", srealm.len, srealm.s,
           vflags, vchecks);

    if(msg->REQ_METHOD==METHOD_REGISTER)
        ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T,
                              &msg->first_line.u.request.method);
    else
        ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T,
                              &msg->first_line.u.request.method);

    if(ret==AUTH_OK && (vflags&AUTH_CHECK_ID_F)) {
        hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
        srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user;

        if((furi=parse_from_uri(msg))==NULL)
            return AUTH_ERROR;

        if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
            if((turi=parse_to_uri(msg))==NULL)
                return AUTH_ERROR;
            uri = turi;
        } else {
            uri = furi;
        }
        if(srealm.len!=uri->user.len
                || strncmp(srealm.s, uri->user.s, srealm.len)!=0)
            return AUTH_USER_MISMATCH;

        if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) {
            /* check from==to */
            if(furi->user.len!=turi->user.len
                    || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
                return AUTH_USER_MISMATCH;
            if(auth_use_domain!=0 && (furi->host.len!=turi->host.len
                                      || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
                return AUTH_USER_MISMATCH;
            /* check r-uri==from for publish */
            if(msg->REQ_METHOD==METHOD_PUBLISH) {
                if(parse_sip_msg_uri(msg)<0)
                    return AUTH_ERROR;
                uri = &msg->parsed_uri;
                if(furi->user.len!=uri->user.len
                        || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
                    return AUTH_USER_MISMATCH;
                if(auth_use_domain!=0 && (furi->host.len!=uri->host.len
                                          || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
                    return AUTH_USER_MISMATCH;
            }
        }
        return AUTH_OK;
    }

    return ret;
}