Beispiel #1
0
/* reads Identity header field from msg
   Return value: 1: success
                 0: Identity header field does not exist
                 1: else
   identityHF must point to an array with at least MAX_IDENTITY bytes
*/
static int getIdentityHF(char * identityHF, struct sip_msg * msg)
{
	struct hdr_field * identity = NULL;

	if(!identityHF || !msg)
	{
		LM_ERR("identityHF or msg not set\n");
		return -1;
	}

	identity = get_header_by_static_name(msg, "Identity");
	if (!identity)
	{
		/* Identity header field does not exist */
		return 0;
	}

	if(((identity->body.len) - 2) >= MAX_IDENTITY)
	{
		LM_ERR("identity header to long\n");
		return -1;
	}

	/* " at the beginning and at the end are cutted */
	memcpy( identityHF, identity->body.s+1, identity->body.len-2);
	identityHF[(identity->body.len) - 2] = '\0';

	return 1;
}
Beispiel #2
0
void get_cancel_reason(struct sip_msg *msg, int flags, str *reason)
{
#define CANCEL_REASON_SIP_487  \
	"Reason: SIP;cause=487;text=\"ORIGINATOR_CANCEL\"" CRLF
	int_str avp_reason;
	struct hdr_field *hdr;

	reason->s = NULL;
	reason->len = 0;

	if (search_first_avp( AVP_VAL_STR, _reason_avp_id, &avp_reason, NULL)) {
		*reason = avp_reason.s;
	} else {
		/* propagate the REASON flag ? */
		if ( flags&T_CANCEL_REASON_FLAG ) {
			/* look for the Reason header */
			if (parse_headers(msg, HDR_EOH_F, 0)<0) {
				LM_ERR("failed to parse all hdrs - ignoring Reason hdr\n");
				} else {
				hdr = get_header_by_static_name(msg, "Reason");
				if (hdr!=NULL) {
					reason->s = hdr->name.s;
					reason->len = hdr->len;
				}
			}
		}
	}

	/* if no reason, use NORMAL CLEARING */
	if (reason->s == NULL) {
		reason->s = CANCEL_REASON_SIP_487;
		reason->len = sizeof(CANCEL_REASON_SIP_487) - 1;
	}
}
Beispiel #3
0
void cancel_invite(struct sip_msg *cancel_msg,
								struct cell *t_cancel, struct cell *t_invite )
{
#define CANCEL_REASON_SIP_487  \
	"Reason: SIP;cause=487;text=\"ORIGINATOR_CANCEL\"" CRLF

	branch_bm_t cancel_bitmap;
	branch_bm_t dummy_bm;
	str reason;
	unsigned int i;
	struct hdr_field *hdr;

	cancel_bitmap=0;

	/* send back 200 OK as per RFC3261 */
	reason.s = CANCELING;
	reason.len = sizeof(CANCELING)-1;
	t_reply( t_cancel, cancel_msg, 200, &reason );

	reason.s = NULL;
	reason.len = 0;
	/* propagate the REASON flag ? */
	if ( t_cancel->flags&T_CANCEL_REASON_FLAG ) {
		/* look for the Reason header */
		if (parse_headers(cancel_msg, HDR_EOH_F, 0)<0) {
			LM_ERR("failed to parse all hdrs - ignoring Reason hdr\n");
		} else {
			hdr = get_header_by_static_name(cancel_msg, "Reason");
			if (hdr!=NULL) {
				reason.s = hdr->name.s;
				reason.len = hdr->len;
			}
		}
	}

	/* if no reason, use NORMAL CLEARING */
	if (reason.s == NULL) {
		reason.s = CANCEL_REASON_SIP_487;
		reason.len = sizeof(CANCEL_REASON_SIP_487) - 1;
	}

	/* generate local cancels for all branches */
	which_cancel(t_invite, &cancel_bitmap );

	set_cancel_extra_hdrs( reason.s, reason.len);
	cancel_uacs(t_invite, cancel_bitmap );
	set_cancel_extra_hdrs( NULL, 0);

	/* internally cancel branches with no received reply */
	for (i=t_invite->first_branch; i<t_invite->nr_of_outgoings; i++) {
		if (t_invite->uac[i].last_received==0){
			/* reset the "request" timers */
			reset_timer(&t_invite->uac[i].request.retr_timer);
			reset_timer(&t_invite->uac[i].request.fr_timer);
			LOCK_REPLIES( t_invite );
			relay_reply(t_invite,FAKED_REPLY,i,487,&dummy_bm);
		}
	}
}
Beispiel #4
0
/* reads the Date header field of msg
   return value: -1: error
                  0: Date header field does not exist
                  1: success

   dateHF must point to an array with at least MAX_TIME bytes
*/
static int getDate(char * dateHF, time_t * dateHFValue, struct sip_msg * msg)
{
	struct hdr_field * date = NULL;
	struct tm tmDate;


	if(!dateHF || !dateHFValue || !msg)
	{
		LM_ERR("dateHF, dateHFValue or msg not set\n");
		return -1;
	}

	date = get_header_by_static_name(msg, "Date");
	if (!date)
	{
		return 0;
	}

	if(date->body.len >= MAX_TIME)
	{
		LM_ERR("Date header field to long\n");
		return -1;
	}

	/* date->body.len < MAX_TIME */
	strncpy(dateHF, date->body.s, date->body.len);
	dateHF[date->body.len] = '\0';

	if(!strptime(dateHF, DATE_FORMAT, &tmDate))
	{
		LM_ERR("error while parsing Date header field\n");
		return -1;
	}

	/* covert struct tm to time_t */
	*dateHFValue = my_timegm(&tmDate);
	if(*dateHFValue == -1)
	{
		LM_ERR("error while converting timestamp\n");
		return -1;
	}

	return 1;
}
Beispiel #5
0
/* builds digest string of msg
   Return value: 1: success
                 0: else
    digestString must point to an array with at least MAX_DIGEST bytes
*/
static int makeDigestString(char * digestString, char * dateHF,
														struct sip_msg * msg)
{
	struct to_body * from = NULL;
	struct to_body * to = NULL;
	struct cseq_body * cseq = NULL;
	struct hdr_field * date = NULL;
	contact_t * contact = NULL;
	unsigned int l;
	str tmp;

	if(!digestString || !msg)
	{
		LM_ERR("not all parameters set\n");
		return 0;
	}

	l = 0;

	/* ###from### */
	if(parse_from_header(msg) != 0)
	{
		LM_ERR("error parsing from header\n");
		return 0;
	}

	from = get_from(msg);
	if(!from)
	{
		LM_ERR("error getting from header\n");
		return 0;
	}

	if (l+from->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 1\n");
		return 0;
	}
	memcpy( digestString+l, from->uri.s, from->uri.len);
	l += from->uri.len;
	*(digestString+(l++)) = '|';

	/* ###To### */
	to = get_to(msg);
	if(!to)
	{
		LM_ERR("error getting to header\n");
		return 0;
	}

	if (l+to->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 2\n");
		return 0;
	}
	memcpy( digestString+l, to->uri.s, to->uri.len);
	l += to->uri.len;
	*(digestString+(l++)) = '|';

	/* ###callid### */
	if(!msg->callid)
	{
		LM_ERR("error getting callid header\n");
		return 0;
	}

	if (l+msg->callid->body.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 3\n");
		return 0;
	}
	memcpy( digestString+l, msg->callid->body.s, msg->callid->body.len);
	l += msg->callid->body.len;
	*(digestString+(l++)) = '|';

	/* ###CSeq### */
	cseq = (struct cseq_body *)msg->cseq->parsed;
	if (!cseq)
	{
		LM_ERR("error getting cseq header\n");
		return 0;
	}

	tmp.s = cseq->number.s;
	tmp.len = cseq->number.len;

	/* strip leading zeros */
	while((*(tmp.s) == '0') && (tmp.len > 1))
	{
		(tmp.s)++;
		(tmp.len)--;
	}

	if (l+tmp.len+cseq->method.len+2>MAX_DIGEST) {
		LM_ERR("buffer to short 4\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = ' ';
	memcpy( digestString+l, cseq->method.s, cseq->method.len);
	l += cseq->method.len;
	*(digestString+(l++)) = '|';

	/* ###Date### */
	if(!dateHF)
	{
		/* Date header field is taken from msg: verifier */
		date = get_header_by_static_name(msg,"Date");
		if (!date)
		{
			LM_ERR("error getting date header\n");
			return 0;
		}
		tmp = date->body;
	}
	else
	{
		/* Date header field is taken from dateHF: authentication service */
		tmp.s = dateHF;
		tmp.len = strlen(tmp.s);
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 5\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = '|';

	/* ###Contact### */
	if(msg->contact)
	{
		if(parse_contact(msg->contact) != 0)
		{
			LM_ERR("error parsing contact header\n");
			return 0;
		}
		/* first contact in list */
		contact = ((contact_body_t *)(msg->contact->parsed))->contacts;
		tmp = contact->uri;
	} else {
		tmp.len = 0;
		tmp.s = 0;
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 6\n");
		return 0;
	}
	if (tmp.len) {
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
	}
	*(digestString+(l++)) = '|';

	/* ###body### */
	if ( get_body(msg,&tmp)!=0 ) {
		LM_ERR("failed to inspect body\n");
		return 0;
	}
	if (tmp.len != 0) {
		if (l+tmp.len+1>MAX_DIGEST) {
			LM_ERR("buffer to short 7\n");
			return 0;
		}
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
		*(digestString+(l++)) = 0;
	}

	LM_DBG("Digest-String=>%s<\n", digestString);
	return 1;
}
/* Take headers to pass on the other side:
 *	Content-Type: 
 *	Allow: 
 *	Supported:
 *	Require
 *	RSeq
 *	Session-Expires
 *	Min-SE
*/
int b2b_extra_headers(struct sip_msg* msg, str* b2bl_key, str* custom_hdrs, str* extra_headers)
{
	char* p;
	struct hdr_field* require_hdr;
	struct hdr_field* rseq_hdr;
	struct hdr_field* subscription_state_hdr;
	struct hdr_field* hdr;
	struct hdr_field* hdrs[HDR_LST_LEN + HDR_DEFAULT_LEN];
	int hdrs_no = 0;
	int len = 0;
	int i;
	int custom_hdrs_len = 0;

	if(msg->content_type)
		hdrs[hdrs_no++] = msg->content_type;
	if(msg->supported)
		hdrs[hdrs_no++] = msg->supported;
	if(msg->allow)
		hdrs[hdrs_no++] = msg->allow;
	if(msg->proxy_require)
		hdrs[hdrs_no++] = msg->proxy_require;
	if(msg->session_expires)
		hdrs[hdrs_no++] = msg->session_expires;
	if(msg->min_se)
		hdrs[hdrs_no++] = msg->min_se;
	if(msg->maxforwards)
		hdrs[hdrs_no++] = msg->maxforwards;
	if(msg->event)
		hdrs[hdrs_no++] = msg->event;
	

	require_hdr = get_header_by_static_name( msg, "Require");
	if(require_hdr)
		hdrs[hdrs_no++] = require_hdr;

	rseq_hdr = get_header_by_static_name( msg, "RSeq");
	if(rseq_hdr)
		hdrs[hdrs_no++] = rseq_hdr;

	subscription_state_hdr = get_header_by_static_name( msg, "Subscription-state");
	if(subscription_state_hdr)
		hdrs[hdrs_no++] = subscription_state_hdr;

	/* add also the custom headers */
	for(i = 0; i< custom_headers_lst_len; i++)
	{
		hdr = get_header_by_name( msg, custom_headers_lst[i].s,
				custom_headers_lst[i].len);
		if(hdr)
		{
			hdrs[hdrs_no++] = hdr;
		}
	}

	/* calculate the length*/
	for(i = 0; i< hdrs_no; i++)
		len += hdrs[i]->len;

	if(init_callid_hdr.len && msg && msg->callid)
		len+= init_callid_hdr.len + msg->callid->len;

	if(len == 0)
		return 0;

	if(custom_hdrs && custom_hdrs->s && custom_hdrs->len)
	{
		custom_hdrs_len = custom_hdrs->len;
		len += custom_hdrs_len;
	}
	extra_headers->s = (char*)pkg_malloc(len);
	if(extra_headers->s == NULL)
	{
		LM_ERR("No more memory\n");
		return -1;
	}

	p = extra_headers->s;

	/* construct the headers string */
	for(i = 0; i< hdrs_no; i++)
	{
		memcpy(p, hdrs[i]->name.s, hdrs[i]->len);
		p += hdrs[i]->len;
	}
	if(custom_hdrs_len)
	{
		memcpy(p, custom_hdrs->s, custom_hdrs_len);
		p += custom_hdrs_len;
	}

	if(init_callid_hdr.s && msg && msg->callid)
	{
		memcpy(p, init_callid_hdr.s, init_callid_hdr.len);
		p += init_callid_hdr.len;
		len = sprintf(p, ": %.*s",
			(int)(msg->callid->name.s +msg->callid->len -msg->callid->body.s),
			msg->callid->body.s);
		p += len;
	}

	extra_headers->len = p - extra_headers->s;

	return 0;
}
Beispiel #7
0
void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
{
	struct hdr_field* hdr= NULL;
	struct sip_msg* msg= NULL;
	ua_pres_t* presentity= NULL;
	unsigned int lexpire= 0;
	str etag;
	unsigned int hash_index, local_index;
	unsigned long pres_id;

	if(ps->param == NULL)
	{
		LM_ERR("NULL parameter\n");
		return;
	}

	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n");
		return;
	}
	LM_DBG("cback param = %lu\n", (unsigned long)*ps->param);

	pres_id = (unsigned long)*ps->param;
	PUA_PARSE_PRES_ID(pres_id, hash_index, local_index);
	LM_DBG("hash_index= %u, local_index= %u\n", hash_index, local_index);

	if(!find_htable(hash_index, local_index))
	{
		LM_ERR("No record found\n");
		return;
	}

	if(msg== FAKED_REPLY)
	{
		LM_DBG("FAKED_REPLY\n");
		goto done;
	}

	if( ps->code>= 300 )
	{
		delete_htable(hash_index, local_index);
		goto done;
	}

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return;
	}
	if(msg->expires== NULL || msg->expires->body.len<= 0)
	{
		LM_ERR("No Expires header found\n");
		return;
	}
	if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
	{
		LM_ERR("cannot parse Expires header\n");
		return;
	}
	lexpire = ((exp_body_t*)msg->expires->parsed)->val;
	LM_DBG("lexpire= %u\n", lexpire);

	if(lexpire == 0)
	{
		delete_htable(hash_index, local_index);
		goto done;
	}
	hdr = get_header_by_static_name( msg, "SIP-ETag");
	if( hdr==NULL ) /* must find SIP-Etag header field in 200 OK msg*/
	{
		LM_ERR("no SIP-ETag header field found\n");
		return;
	}
	etag= hdr->body;

	update_htable(hash_index, local_index, lexpire, &etag, 0);

done:
	lock_get(&HashT->p_records[hash_index].lock);
	presentity = get_htable_safe(hash_index, local_index);
	if(!presentity)
	{
		LM_DBG("Record not found\n");
		lock_release(&HashT->p_records[hash_index].lock);
		return;
	}

	if(presentity->ua_flag == REQ_OTHER)
	{
		run_pua_callbacks(presentity, msg);
		presentity->cb_param = NULL;
	}
	presentity->waiting_reply = 0;
	while(presentity->pending_publ)
	{
		publ_t* pending_publ = presentity->pending_publ;
		publ_info_t* publ = construct_pending_publ(presentity);
		if(publ == NULL)
		{
			LM_ERR("Failed to create publish record\n");
			lock_release(&HashT->p_records[hash_index].lock);
			presentity->pending_publ = pending_publ->next;
			shm_free(pending_publ);
			continue;
		}
		LM_DBG("Found pending publish\n");
		presentity->pending_publ  = 0;
		presentity->waiting_reply = 1;
		send_publish_int(presentity, publ, get_event(presentity->event),
				presentity->hash_index);
		pkg_free(publ);
		presentity->pending_publ = pending_publ->next;
		shm_free(pending_publ);
		break;
	}

	lock_release(&HashT->p_records[hash_index].lock);
}
Beispiel #8
0
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
{
	publ_info_t publ;
	struct to_body *pto= NULL, TO, *pfrom = NULL;
	str body;
	ua_pres_t dialog;
	unsigned int expires= 0;
	struct hdr_field* hdr;
	str subs_state;
	str extra_headers= {0, 0};
	static char buf[255];
	str contact;

	memset(&publ, 0, sizeof(publ_info_t));
	memset(&dialog, 0, sizeof(ua_pres_t));

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

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}
	/* examine the to header */
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0)
		{
			LM_DBG("'To' header NOT parsed\n");
			return -1;
		}
		pto = &TO;
	}
	publ.pres_uri= &pto->uri;
	dialog.watcher_uri= publ.pres_uri;

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("NULL to_tag value\n");
		return -1;
	}
	dialog.from_tag= pto->tag_value;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		return -1;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		return -1;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG(" 'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_DBG(" ERROR cannot parse From header\n");
			return -1;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.to_uri= pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if ( get_content_length(msg) == 0 )
	{
		LM_DBG("content length= 0\n");
		return 1;
	}
	else
	{
		body.s=get_body(msg);
		if (body.s== NULL)
		{
			LM_ERR("cannot extract body from msg\n");
			return -1;
		}
		body.len = get_content_length( msg );

		if (!bla_body_is_valid( &body ))
		{
			LM_ERR("bad XML body!");
			return -1;
		}
	}
   	
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		return -1;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		return -1;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		return -1;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	dialog.to_tag= pfrom->tag_value;
	dialog.event= BLA_EVENT;
	dialog.flag= BLA_SUBSCRIBE;
	if(pua_is_dialog(&dialog)< 0)
	{
		LM_ERR("Notify in a non existing dialog\n");
		return -2;
	}

	/* parse Subscription-State and extract expires if existing */
	hdr = get_header_by_static_name( msg, "Subscription-State");
	if( hdr==NULL )
	{
		LM_ERR("No Subscription-State header found\n");
		return -1;
	}
	subs_state= hdr->body;
	if(strncasecmp(subs_state.s, "terminated", 10)== 0)
		expires= 0;
	else
	{
		if(strncasecmp(subs_state.s, "active", 6)== 0 ||
				strncasecmp(subs_state.s, "pending", 7)==0 )
		{
			expires = DEFAULT_EXPIRES;
			char* sep= NULL;
			str exp= {NULL, 0};
			sep= strchr(subs_state.s, ';');
			if(sep)
			{
				if(strncasecmp(sep+1, "expires=", 8)== 0)
				{
					exp.s= sep+ 9;
					sep= exp.s;
					while((*sep)>='0' && (*sep)<='9')
					{
						sep++;
						exp.len++;
					}
					if( str2int(&exp, &expires)< 0)
					{
						LM_ERR("while parsing int\n");
						return -1;
					}
				}
			}
		}
		else
		{
			LM_ERR("unknown Subscription-state token\n");
			return -1;
		}
	}

	/* +2 for ": " between header name and value */
	if ((header_name.len + 2 + contact.len + CRLF_LEN) >= sizeof(buf)) {
		LM_ERR("Sender header too large");
		return -1;
	}

	/* build extra_headers with Sender*/
	extra_headers.s= buf;
	memcpy(extra_headers.s, header_name.s, header_name.len);
	extra_headers.len= header_name.len;
	memcpy(extra_headers.s+extra_headers.len,": ",2);
	extra_headers.len+= 2;
	memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
	extra_headers.len+= contact.len;
	memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
	extra_headers.len+= CRLF_LEN;

	publ.id= contact;
	publ.body= &body;
	publ.source_flag= BLA_PUBLISH;
	publ.expires= expires;
	publ.event= BLA_EVENT;
	publ.extra_headers= &extra_headers;
	publ.outbound_proxy = presence_server;

	if(pua_send_publish(&publ)< 0)
	{
		LM_ERR("failed to send Publish message\n");
		return -1;
	}

	return 1;
}
Beispiel #9
0
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, *pfrom= NULL;
	str to_uri;
	str from_uri={0, 0};
	struct hdr_field* hdr= NULL;
	str body;
	xmlDocPtr doc= NULL;
	int is_terminated= 0;
	str id;
	ua_pres_t dialog;
	int event_flag= 0;
	char buf_to[256];

	memset(&dialog, 0, sizeof(ua_pres_t));

	LM_DBG("start...\n\n");

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return -1;
	}

	dialog.watcher_uri= &pto->uri;

	URI_ADD_NULL_TERM(to_uri, buf_to, dialog.watcher_uri);

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		goto error;
	}
	id=  pto->tag_value;
	dialog.from_tag= id;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("ERROR cannot find 'from' header!\n");
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_ERR("ERROR cannot parse From header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	from_uri.s = xmpp_uri_sip2xmpp(dialog.pres_uri);
	if(from_uri.s == 0)
	{
		LM_ERR("Failed to translate uri from sip to xmpp [%.*s]\n",
				dialog.pres_uri->len, dialog.pres_uri->s);
		goto error;
	}
	from_uri.len= strlen(from_uri.s);

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

	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= XMPP_SUBSCRIBE;
	if(msg->event->body.len== 8 &&
			(strncasecmp(msg->event->body.s,"presence",8 )==0))
		event_flag|= PRESENCE_EVENT;
	else
	if(msg->event->body.len== 14 &&
			(strncasecmp(msg->event->body.s,"presence.winfo",14 )==0))
		event_flag|= PWINFO_EVENT;
	else
	{
		LM_ERR("wrong event\n");
		goto error;
	}
	dialog.event= event_flag;

	if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog
	{
		LM_ERR("Notify in a non existing dialog\n");
		goto error;
	}
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{
		body.s= NULL;
		body.len= 0;
	}
	else
	{
		if ( get_body(msg,&body)!=0 || body.len==0)
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
	}

	/* treat the two cases: event= presence & event=presence.winfo */
	if(event_flag & PRESENCE_EVENT)
	{
		LM_DBG("PRESENCE\n");
		hdr = get_header_by_static_name( msg, "Subscription-State" );
		if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0)
		{
			/* chack if reason timeout => don't send notification */
			if(strncasecmp(hdr->body.s+11,"reason=timeout", 14)== 0)
			{
				LM_DBG("Received Notification with state"
					"terminated; reason= timeout=> don't send notification\n");
				return 1;
			}
			is_terminated= 1;

		}

		if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0)
		{
			LM_ERR("in function build_xmpp_content\n");
			goto error;
		}
		xmlFreeDoc(doc);
	}
	else
	{
		if(event_flag & PWINFO_EVENT)
		{
			LM_DBG("PRESENCE.WINFO\n");
			hdr = get_header_by_static_name( msg, "Subscription-State" );
			if(hdr && strncasecmp(hdr->body.s,"terminated", 10)== 0)
			{
				LM_DBG("Notify for presence.winfo with"
					" Subscription-State terminated- should not translate\n");
				goto error;
			}
			if(winfo2xmpp(&to_uri, &body, &id)< 0)
			{
				LM_ERR("while sending subscription\n");
				goto error;
			}

		}
		else
		{
			LM_ERR("Missing or unsupported event header field value\n");
			goto error;
		}

	}
	return 1;

error:
	if(doc)
		xmlFreeDoc(doc);
	return 0;
}
Beispiel #10
0
int b2b_extra_headers(struct sip_msg* msg, str* b2bl_key, str* custom_hdrs,
															str* extra_headers)
{
	char* p;
	struct hdr_field* require_hdr;
	struct hdr_field* rseq_hdr;
	struct hdr_field* subscription_state_hdr;
	struct hdr_field* hdr;
	struct hdr_field* hdrs[HDR_LST_LEN + HDR_DEFAULT_LEN];
	regmatch_t pmatch;
	int hdrs_no = 0;
	int len = 0;
	int i;
	int custom_hdrs_len = 0;
	char tmp;

	if(msg->content_type)
		hdrs[hdrs_no++] = msg->content_type;
	if(msg->supported)
		hdrs[hdrs_no++] = msg->supported;
	if(msg->allow)
		hdrs[hdrs_no++] = msg->allow;
	if(msg->proxy_require)
		hdrs[hdrs_no++] = msg->proxy_require;
	if(msg->session_expires)
		hdrs[hdrs_no++] = msg->session_expires;
	if(msg->min_se)
		hdrs[hdrs_no++] = msg->min_se;
	if(msg->event)
		hdrs[hdrs_no++] = msg->event;


	require_hdr = get_header_by_static_name( msg, "Require");
	if(require_hdr)
		hdrs[hdrs_no++] = require_hdr;

	rseq_hdr = get_header_by_static_name( msg, "RSeq");
	if(rseq_hdr)
		hdrs[hdrs_no++] = rseq_hdr;

	subscription_state_hdr = get_header_by_static_name( msg,
		"Subscription-state");
	if(subscription_state_hdr)
		hdrs[hdrs_no++] = subscription_state_hdr;

	/* add also the custom headers */
	for(i = 0; i< custom_headers_lst_len; i++)
	{
		hdr = get_header_by_name( msg, custom_headers_lst[i].s,
				custom_headers_lst[i].len);
		if(hdr)
		{
			hdrs[hdrs_no++] = hdr;
		}
	}

	if (custom_headers_re)
	{
		for (hdr=msg->headers; hdr; hdr=hdr->next) {
			tmp = hdr->name.s[hdr->name.len];
			hdr->name.s[hdr->name.len] = '\0';
			i = regexec(custom_headers_re, hdr->name.s, 1, &pmatch, 0);
			hdr->name.s[hdr->name.len] = tmp;

			if (i == 0)
			{
				/* check if added twice */
				for(i = 0; i < hdrs_no; i++)
				{
					if ( hdrs[i]->name.len == hdr->name.len &&
					strncmp(hdrs[i]->name.s, hdr->name.s, hdr->name.len)==0 )
						break;
				}
				if (i == hdrs_no) /* Doubles not found -> add it */
					hdrs[hdrs_no++] = hdr;
			}
		}
	}

	/* calculate the length*/
	for(i = 0; i< hdrs_no; i++)
		len += hdrs[i]->len;

	if(init_callid_hdr.len && msg && msg->callid)
		len+= init_callid_hdr.len + msg->callid->len;

	if(custom_hdrs && custom_hdrs->s && custom_hdrs->len)
	{
		custom_hdrs_len = custom_hdrs->len;
		len += custom_hdrs_len;
	}

	if(len == 0) return 0;

	extra_headers->s = (char*)pkg_malloc(len);
	if(extra_headers->s == NULL)
	{
		LM_ERR("No more memory\n");
		return -1;
	}

	p = extra_headers->s;

	/* construct the headers string */
	for(i = 0; i< hdrs_no; i++)
	{
		memcpy(p, hdrs[i]->name.s, hdrs[i]->len);
		p += hdrs[i]->len;
	}
	if(custom_hdrs_len)
	{
		memcpy(p, custom_hdrs->s, custom_hdrs_len);
		p += custom_hdrs_len;
	}

	if(init_callid_hdr.s && msg && msg->callid)
	{
		memcpy(p, init_callid_hdr.s, init_callid_hdr.len);
		p += init_callid_hdr.len;
		len = sprintf(p, ": %.*s",
			(int)(msg->callid->name.s +msg->callid->len -msg->callid->body.s),
			msg->callid->body.s);
		p += len;
	}

	extra_headers->len = p - extra_headers->s;

	return 0;
}
Beispiel #11
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;
}
int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
{
	struct to_body *pto, *pfrom= NULL;
	str body= {0, 0};
	ua_pres_t dialog;
	str* res_id= NULL;
	db_key_t query_cols[9], result_cols[1];
	db_val_t query_vals[9];
	db_res_t* result= NULL;
	int n_query_cols= 0;
	str auth_state= {0, 0};
	str* reason= NULL;
	int auth_flag;
	struct hdr_field* hdr= NULL;
	int n, expires= -1;
	str ctype= {0, 0};
	int err_ret = -1;

	LM_DBG("start\n");
	/* extract the dialog information and check if an existing dialog*/	
	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}
	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}

	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return -1;
	}

	memset(&dialog, 0, sizeof(ua_pres_t));
	dialog.watcher_uri= &pto->uri;
    if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{  
		LM_ERR("to tag value not parsed\n");
		goto error;
	}

	dialog.from_tag= pto->tag_value;
	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG("'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 ) 
		{
			LM_ERR("cannot parse From header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;
		
	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}
	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= RLS_SUBSCRIBE;

	dialog.event= get_event_flag(&msg->event->body);
	if(dialog.event< 0)
	{
		LM_ERR("unrecognized event package\n");
		goto error;
	}
	if(pua_get_record_id(&dialog, &res_id)< 0) // verify if within a stored dialog
	{
		LM_ERR("error occured while trying to get dialog record id\n");
		goto error;
	}
	if(res_id== 0)
	{
		LM_DBG("no dialog match found in hash table\n");
		err_ret = 2;
		goto error;
	}

	/* extract the subscription state */
	hdr = get_header_by_static_name( msg, "Subscription-State");
	if( hdr==NULL )
	{
		LM_ERR("'Subscription-State' header not found\n");
		goto error;
	}
	auth_state = hdr->body;

	/* extract state and reason */
	auth_flag= parse_subs_state(auth_state, &reason, &expires);
	if(auth_flag< 0)
	{
		LM_ERR("while parsing 'Subscription-State' header\n");
		goto error;
	}
	if(msg->content_type== NULL || msg->content_type->body.s== NULL)
	{
		LM_DBG("cannot find content type header\n");
	}
	else
		ctype= msg->content_type->body;

	LM_DBG("NOTIFY for [user]= %.*s\n",dialog.pres_uri->len,
			dialog.pres_uri->s);
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{
		LM_DBG("null body\n");
		goto done;
	}	
	else
	{
		if(ctype.s== 0)
		{
			LM_ERR("content length != 0 and no content type header found\n");
			goto error;
		}
		if ( get_body(msg,&body)!=0 || body.len==0)
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		LM_DBG("[body]= %.*s\n", body.len, body.s);
	}
	
	/* update in rlpres_table where rlsusb_did= res_id and resource_uri= from_uri*/

	query_cols[n_query_cols]= &str_rlsubs_did_col;
	query_vals[n_query_cols].type = DB_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *res_id; 
	n_query_cols++;
	
	query_cols[n_query_cols]= &str_resource_uri_col;
	query_vals[n_query_cols].type = DB_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *dialog.pres_uri; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_updated_col;
	query_vals[n_query_cols].type = DB_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= UPDATED_TYPE; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_auth_state_col;
	query_vals[n_query_cols].type = DB_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= auth_flag; 
	n_query_cols++;

	if(reason)
	{
		query_cols[n_query_cols]= &str_reason_col;
		query_vals[n_query_cols].type = DB_STR;
		query_vals[n_query_cols].nul = 0;
		query_vals[n_query_cols].val.str_val= *reason;
		n_query_cols++;
	}
	query_cols[n_query_cols]= &str_content_type_col;
	query_vals[n_query_cols].type = DB_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= ctype;
	n_query_cols++;

	query_cols[n_query_cols]= &str_presence_state_col;
	query_vals[n_query_cols].type = DB_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= body;
	n_query_cols++;
	
	query_cols[n_query_cols]= &str_expires_col;
	query_vals[n_query_cols].type = DB_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL);
	n_query_cols++;

	if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto error;
	}
	/* query-> if not present insert // else update */
	result_cols[0]= &str_updated_col;

	if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
					2, 1, 0, &result)< 0)
	{
		LM_ERR("in sql query\n");
		if(result)
			rls_dbf.free_result(rls_db, result);
		goto error;
	}
	if(result== NULL)
		goto error;
	n= result->n;
	rls_dbf.free_result(rls_db, result);

	if(n<= 0)
	{
		if(rls_dbf.insert(rls_db, query_cols, query_vals, n_query_cols)< 0)
		{
			LM_ERR("in sql insert\n");
			goto error;
		}
	}
	else
	{
		if(expires!= 0)
		{
			if(rls_dbf.update(rls_db, query_cols, 0, query_vals, query_cols+2,
						query_vals+2, 2, n_query_cols-2)< 0)
			{
				LM_ERR("in sql update\n");
				goto error;
			}
		}
		else  /* if terminated - delete from rls_presentity table */
		{
			if(rls_dbf.delete(rls_db, query_cols, 0, query_vals, 2)< 0)
			{
				LM_ERR("sql delete failed\n");
				goto error;
			}

		}
	}
	
done:
	if( rls_sigb.reply(msg, 200, &su_200_rpl, 0) < 0)
	{
		LM_ERR("failed to send SIP reply\n");
		goto error;
	}	
	pkg_free(res_id->s);
	pkg_free(res_id);

	return 1;

error:
	if(res_id)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	return err_ret;
}