Esempio n. 1
0
static int
alter_mediaip(struct sip_msg *msg, str *body, str *oldip, str *newip,
  int *clendelta, int preserve)
{
	char *buf;
	int offset;
	struct lump* anchor;

	/* check that updating mediaip is really necessary */
	if (7 == oldip->len && memcmp("0.0.0.0", oldip->s, 7) == 0)
		return 0;
	if (newip->len == oldip->len &&
	    memcmp(newip->s, oldip->s, newip->len) == 0)
		return 0;

	if (preserve != 0) {
		anchor = anchor_lump(&(msg->add_rm),
		    body->s + body->len - msg->buf, 0, 0);
		if (anchor == NULL) {
			LOG(L_ERR, "ERROR: alter_mediaip: anchor_lump failed\n");
			return -1;
		}
		buf = pkg_malloc(AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN);
		if (buf == NULL) {
			LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n");
			return -1;
		}
		memcpy(buf, AOLDMEDIAIP, AOLDMEDIAIP_LEN);
		memcpy(buf + AOLDMEDIAIP_LEN, oldip->s, oldip->len);
		memcpy(buf + AOLDMEDIAIP_LEN + oldip->len, CRLF, CRLF_LEN);
		if (insert_new_lump_after(anchor, buf,
		    AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN, 0) == NULL) {
			LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n");
			pkg_free(buf);
			return -1;
		}
		*clendelta += AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN;
	}

	buf = pkg_malloc(newip->len);
	if (buf == NULL) {
		LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n");
		return -1;
	}
	offset = oldip->s - msg->buf;
	anchor = del_lump(&msg->add_rm, offset, oldip->len, 0);
	if (anchor == NULL) {
		LOG(L_ERR, "ERROR: alter_mediaip: del_lump failed\n");
		pkg_free(buf);
		return -1;
	}
	memcpy(buf, newip->s, newip->len);
	if (insert_new_lump_after(anchor, buf, newip->len, 0) == 0) {
		LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n");
		pkg_free(buf);
		return -1;
	}
	*clendelta += newip->len - oldip->len;
	return 0;
}
Esempio n. 2
0
static int do_replace_body_f(struct sip_msg* msg, char* key, char* str2, int nobol)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int len;
	char* begin;
	int off;
	int ret;
	int eflags;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	begin=body.s;
	ret=-1; /* pessimist: we will not find any */
	len=strlen(str2);
	eflags=0; /* match ^ at the beginning of the string*/

	while (begin<msg->buf+msg->len
				&& regexec((regex_t*) key, begin, 1, &pmatch, eflags)==0) {
		off=begin-msg->buf;
		if (pmatch.rm_so==-1){
			LM_ERR("offset unknown\n");
			return -1;
		}
		if (pmatch.rm_so==pmatch.rm_eo){
			LM_ERR("matched string is empty... invalid regexp?\n");
			return -1;
		}
		if ((l=del_lump(msg, pmatch.rm_so+off,
						pmatch.rm_eo-pmatch.rm_so, 0))==0) {
			LM_ERR("del_lump failed\n");
			return -1;
		}
		s=pkg_malloc(len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2, len);
		if (insert_new_lump_after(l, s, len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		/* new cycle */
		begin=begin+pmatch.rm_eo;
		/* is it still a string start */
		if (nobol && (*(begin-1)=='\n' || *(begin-1)=='\r'))
			eflags&=~REG_NOTBOL;
		else
			eflags|=REG_NOTBOL;
		ret=1;
	} /* while found ... */
	return ret;
}
Esempio n. 3
0
static int insert_header_lump(struct sip_msg* msg, char* msg_position, int lump_before, str* hname, str *val) {
	struct lump* anchor;
	char *s;
	int len;

	anchor = anchor_lump(msg, msg_position - msg->buf, 0, 0);
	if (anchor == 0) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't get anchor\n");
		return -1;
	}

	len=hname->len+2+val->len+2;

	s = (char*)pkg_malloc(len);
	if (!s) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): not enough memory\n");
		return -1;
	}

	memcpy(s, hname->s, hname->len);
	s[hname->len] = ':';
	s[hname->len+1] = ' ';
	memcpy(s+hname->len+2, val->s, val->len);
	s[hname->len+2+val->len] = '\r';
	s[hname->len+2+val->len+1] = '\n';

	if ( (lump_before?insert_new_lump_before(anchor, s, len, 0):insert_new_lump_after(anchor, s, len, 0)) == 0) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't insert lump\n");
		pkg_free(s);
		return -1;
	}
	return 1;
}
static Bool
replaceElement(struct sip_msg *msg, str *oldElem, str *newElem)
{
    struct lump* anchor;
    char *buf;

    if (newElem->len==oldElem->len &&
        memcmp(newElem->s, oldElem->s, newElem->len)==0) {
        return True;
    }

    buf = pkg_malloc(newElem->len);
    if (!buf) {
        LOG(L_ERR, "error: mediaproxy/replaceElement(): out of memory\n");
        return False;
    }

    anchor = del_lump(msg, oldElem->s - msg->buf, oldElem->len, 0);
    if (!anchor) {
        LOG(L_ERR, "error: mediaproxy/replaceElement(): failed to delete old element\n");
        pkg_free(buf);
        return False;
    }

    memcpy(buf, newElem->s, newElem->len);

    if (insert_new_lump_after(anchor, buf, newElem->len, 0)==0) {
        LOG(L_ERR, "error: mediaproxy/replaceElement(): failed to insert new element\n");
        pkg_free(buf);
        return False;
    }

    return True;
}
Esempio n. 5
0
static int search_append_f(struct sip_msg* msg, char* key, char* str)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int len;
	char *begin;
	int off;

	begin=get_header(msg); /* msg->orig/buf previously .. uri problems */
	off=begin-msg->buf;

	if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
	if (pmatch.rm_so!=-1){
		if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0, 0))==0)
			return -1;
		len=strlen(str);
		s=pkg_malloc(len);
		if (s==0){
			LOG(L_ERR, "ERROR: search_append_f: mem. allocation failure\n");
			return -1;
		}
		memcpy(s, str, len); 
		if (insert_new_lump_after(l, s, len, 0)==0){
			LOG(L_ERR, "ERROR: could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		return 1;
	}
	return -1;
}
Esempio n. 6
0
/* Creates the necessary lumps in order to push the new header value.
 * The whole change/update value process (for the header) is based on a
 * anchoring lump tree that deletes the header and adds the future new values.
 * A chain of "DEL-> SKIP->" is fix and the the new values will be chained
 * on the "after" SKIP branch
 * This works as a multi-time full hdr header replacement (covering hdr name 
 * and CRLF)
 */
static inline struct lump* _push_changes_into_lumps(struct sip_msg *msg,
						struct lump *l, struct hdr_field *hdr, str *body)
{
	struct lump *l1;

	/* is this the first change ? */
	if (l==NULL) {

		/* first change, so build on the static anchoring lump tree (where
		 * all the future changes will be attached ) */
		l = del_lump(msg, hdr->name.s-msg->buf, hdr->len, hdr->type);
		if (l==NULL) {
			LM_ERR("failed to insert del lump\n");
			return NULL;
		}
		l->flags |= LUMP_FLAG_LISTHDR;

		l = insert_skip_lump_after( l );
		if (l==NULL) {
			LM_ERR("failed to insert new skip lump after del\n");
			return NULL;
		}

	}

	/* add the new value to the existing anchoring lump tree */

	l1 = insert_new_lump_after( l, body->s, body->len, hdr->type);
	if (l1==NULL) {
		LM_ERR("failed to insert new lump after skip\n");
		return NULL;
	}

	return l1;
}
Esempio n. 7
0
static int clone_codec_lumps(void)
{
	struct lump *l;
	int i;
	char *s;

	LM_DBG("cloning %d streams\n",lumps_len);

	for( i=0 ; i<lumps_len ; i++ ) {
		/* get last lump for stream */
		for( l=lumps[i] ; l->after ; l=l->after );

		s = pkg_malloc( l->len+1 );
		if (s==NULL) {
			LM_ERR("failed to alloc new lump pkg buffer\n");
			return -1;
		}
		memcpy( s, l->u.value, l->len);

		if (insert_new_lump_after( l, s, l->len, 0)==NULL) {
			LM_ERR("failed to create new lump\n");
			return -1;
		}
	}

	return 0;
}
Esempio n. 8
0
int replace_sdp_stream_port(struct sip_msg *msg, struct sdp_stream_cell *stream,
                            unsigned int transcoder_port)
{
	struct lump *lump;
	char *p;

	lump = del_lump(msg, stream->port.s - msg->buf,
	                stream->port.len, HDR_OTHER_T);
	if (!lump) {
		LM_ERR("failed to add del lump\n");
		return -1;
	}

	p = pkg_malloc(6);
	if (!p) {
		LM_ERR("no more pkg mem\n");
		return -1;
	}

	sprintf(p, "%d", transcoder_port);

	if (!insert_new_lump_after(lump, p, strlen(p), HDR_OTHER_T)) {
		LM_ERR("no more pkg mem\n");
		return -1;
	}

	return 0;
}
Esempio n. 9
0
int
patch (struct sip_msg *msg, char *oldstr, unsigned int oldlen, char *newstr,
       unsigned int newlen)
{
	int off;
	struct lump *anchor;

	if (oldstr == NULL)
		return -1;

	if (newstr == NULL)
		return -2;
	off = oldstr - msg->buf;
	if (off < 0)
		return -3;
	if ((anchor = del_lump (msg, off, oldlen, 0)) == 0)
	{
		LM_ERR("lumping with del_lump\n");
		return -4;
	}
	if ((insert_new_lump_after (anchor, newstr, newlen, 0)) == 0)
	{
		LM_ERR("lumping with insert_new_lump_after\n");
		return -5;
	}

	return 0;
}
Esempio n. 10
0
static int replace_f(struct sip_msg* msg, regex_t* key, str* str2)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	char* begin;
	int off;

	begin=get_header(msg); /* msg->orig previously .. uri problems */

	if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
	off=begin-msg->buf;

	if (pmatch.rm_so!=-1){
		if ((l=del_lump(msg, pmatch.rm_so+off,
						pmatch.rm_eo-pmatch.rm_so, 0))==0)
			return -1;
		s=pkg_malloc(str2->len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2->s, str2->len);
		if (insert_new_lump_after(l, s, str2->len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}

		return 1;
	}
	return -1;
}
Esempio n. 11
0
static int search_append_body_f(struct sip_msg* msg, regex_t* key, str* str2)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int off;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	off=body.s-msg->buf;

	if (regexec(key, body.s, 1, &pmatch, 0)!=0) return -1;
	if (pmatch.rm_so!=-1){
		if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0))==0)
			return -1;
		s=pkg_malloc(str2->len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2->s, str2->len);
		if (insert_new_lump_after(l, s, str2->len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		return 1;
	}
	return -1;
}
Esempio n. 12
0
int th_unmask_ruri(sip_msg_t *msg)
{
	str eval;
	struct lump* l;
	str out;

	if(th_get_uri_param_value(&REQ_LINE(msg).uri, &th_uparam_name, &eval)<0
			|| eval.len<=0)
		return -1;
	
	out.s = th_mask_decode(eval.s, eval.len,
				&th_uparam_prefix, 0, &out.len);
	if(out.s==NULL)
	{
		LM_ERR("cannot decode r-uri\n");
		return -1;
	}
					
	LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
	l=del_lump(msg, REQ_LINE(msg).uri.s-msg->buf, REQ_LINE(msg).uri.len, 0);
	if (l==0)
	{
		LM_ERR("failed deleting r-uri\n");
		pkg_free(out.s);
		return -1;
	}
	if (insert_new_lump_after(l, out.s, out.len, 0)==0)
	{
		LM_ERR("could not insert new lump\n");
		pkg_free(out.s);
		return -1;
	}

	return 0;
}
Esempio n. 13
0
static int
update_clen(struct sip_msg* msg, int newlen)
{
	char *buf;
	int len, offset;
	struct lump* anchor;

	buf = pkg_malloc(CLEN_LEN * sizeof(char));
	if (buf == NULL) {
		LOG(L_ERR, "ERROR: update_clen: out of memory\n");
		return -1;
	}
	offset = msg->content_length->body.s - msg->buf;
	len = msg->content_length->body.len;
	anchor = del_lump(&msg->add_rm, offset, len, HDR_CONTENTLENGTH);
	if (anchor == NULL) {
		LOG(L_ERR, "ERROR: update_clen: del_lump failed\n");
		pkg_free(buf);
		return -1;
	}
	len = snprintf(buf, CLEN_LEN, "%d", newlen);
	if (len >= CLEN_LEN)
		len = CLEN_LEN - 1;
	if (insert_new_lump_after(anchor, buf, len, HDR_CONTENTLENGTH) == NULL) {
		LOG(L_ERR, "ERROR: update_clen: insert_new_lump_after failed\n");
		pkg_free(buf);
		return -1;
	}

	return 1;
}
Esempio n. 14
0
/*
 * Replaces ip:port pair in the Contact: field with the source address
 * of the packet and/or adds direction=active option to the SDP.
 */
static int
fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2)
{
	int offset, len, len1;
	char *cp, *buf, temp[2];
	contact_t* c;
	struct lump* anchor;
	struct sip_uri uri;

	if ((parse_headers(msg, HDR_CONTACT, 0) == -1) || !msg->contact)
		return -1;
	if (!msg->contact->parsed && parse_contact(msg->contact) < 0) {
		LOG(L_ERR, "fix_nated_contact: Error while parsing Contact body\n");
		return -1;
	}
	c = ((contact_body_t*)msg->contact->parsed)->contacts;
	if (!c) {
		LOG(L_ERR, "fix_nated_contact: Error while parsing Contact body\n");
		return -1;
	}
	if (parse_uri(c->uri.s, c->uri.len, &uri) < 0 || uri.host.len <= 0) {
		LOG(L_ERR, "fix_nated_contact: Error while parsing Contact URI\n");
		return -1;
	}
	if (uri.proto != PROTO_UDP && uri.proto != PROTO_NONE)
		return 0;
	if (uri.port.len == 0)
		uri.port.s = uri.host.s + uri.host.len;

	offset = c->uri.s - msg->buf;
	anchor = del_lump(&msg->add_rm, offset, c->uri.len, HDR_CONTACT);
	if (anchor == 0)
		return -1;

	cp = ip_addr2a(&msg->rcv.src_ip);
	len = c->uri.len + strlen(cp) + 6 /* :port */ - (uri.port.s + uri.port.len - uri.host.s) + 1;
	buf = pkg_malloc(len);
	if (buf == NULL) {
		LOG(L_ERR, "ERROR: fix_nated_contact: out of memory\n");
		return -1;
	}
	temp[0] = uri.host.s[0];
	temp[1] = c->uri.s[c->uri.len];
	c->uri.s[c->uri.len] = uri.host.s[0] = '\0';
	len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp, msg->rcv.src_port,
	    uri.port.s + uri.port.len);
	if (len1 < len)
		len = len1;
	uri.host.s[0] = temp[0];
	c->uri.s[c->uri.len] = temp[1];
	if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT) == 0) {
		pkg_free(buf);
		return -1;
	}
	c->uri.s = buf;
	c->uri.len = len;

	return 1;
}
Esempio n. 15
0
static int change_reply_status_f(struct sip_msg* msg, char* _code, char* _reason)
{
	int	code;
	str	reason;
	struct lump	*l;
	char	*ch;

	if (get_int_fparam(&code, msg, (fparam_t*)_code)
		|| get_str_fparam(&reason, msg, (fparam_t*)_reason)
		|| (reason.len == 0)
	) {
		LOG(L_ERR, "ERROR: textops: cannot get parameter\n");
		return -1;
	}

	if ((code < 100) || (code > 699)) {
		LOG(L_ERR, "ERROR: textops: wrong status code: %d\n",
				code);
		return -1;
	}

	if (((code < 300) || (msg->REPLY_STATUS < 300))
		&& (code/100 != msg->REPLY_STATUS/100)
	) {
		LOG(L_ERR, "ERROR: textops: the class of provisional or "
			"positive final replies cannot be changed\n");
		return -1;
	}

	/* rewrite the status code directly in the message buffer */
	msg->first_line.u.reply.statuscode = code;
	msg->first_line.u.reply.status.s[2] = code % 10 + '0'; code /= 10;
	msg->first_line.u.reply.status.s[1] = code % 10 + '0'; code /= 10;
	msg->first_line.u.reply.status.s[0] = code + '0';

	l = del_lump(msg,
		msg->first_line.u.reply.reason.s - msg->buf,
		msg->first_line.u.reply.reason.len,
		0);
	if (!l) {
		LOG(L_ERR, "ERROR: textops(): Failed to add del lump\n");
		return -1;
	}
	/* clone the reason phrase, the lumps need to be pkg allocated */
	ch = (char *)pkg_malloc(reason.len);
	if (!ch) {
		LOG(L_ERR, "ERROR: textops: Not enough memory\n");
		return -1;
	}
	memcpy(ch, reason.s, reason.len);
	if (insert_new_lump_after(l, ch, reason.len, 0)==0){
		LOG(L_ERR, "ERROR: textops: failed to add new lump: %.*s\n",
			reason.len, ch);
		pkg_free(ch);
		return -1;
	}

	return 1;
}
Esempio n. 16
0
/*
 * Replaces ip:port pair in the Contact: field with the source address
 * of the packet.
 */
static int
fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2)
{
	int offset, len, len1;
	char *cp, *buf, temp[2];
	contact_t *c;
	struct lump *anchor;
	struct sip_uri uri;
	str hostport;

	if (get_contact_uri(msg, &uri, &c) == -1)
		return -1;
	/* for UAs behind NAT we have to hope that they will reuse the
	 * TCP connection, otherwise they are lost any way. So this check
	 * does not make too much sense.
	if (uri.proto != PROTO_UDP && uri.proto != PROTO_NONE)
		return -1;
	*/
	if ((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
		LOG(L_ERR, "ERROR: you can't call fix_nated_contact twice, "
		    "check your config!\n");
		return -1;
	}

	offset = c->uri.s - msg->buf;
	anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T);
	if (anchor == 0)
		return -1;

	hostport = uri.host;
	if (uri.port.len > 0)
		hostport.len = uri.port.s + uri.port.len - uri.host.s;

	cp = ip_addr2a(&msg->rcv.src_ip);
	len = c->uri.len + strlen(cp) + 6 /* :port */ - hostport.len + 1;
	buf = pkg_malloc(len);
	if (buf == NULL) {
		LOG(L_ERR, "ERROR: fix_nated_contact: out of memory\n");
		return -1;
	}
	temp[0] = hostport.s[0];
	temp[1] = c->uri.s[c->uri.len];
	c->uri.s[c->uri.len] = hostport.s[0] = '\0';
	len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp, msg->rcv.src_port,
	    hostport.s + hostport.len);
	if (len1 < len)
		len = len1;
	hostport.s[0] = temp[0];
	c->uri.s[c->uri.len] = temp[1];
	if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) {
		pkg_free(buf);
		return -1;
	}
	c->uri.s = buf;
	c->uri.len = len;

	return 1;
}
Esempio n. 17
0
int th_unmask_refer_to(sip_msg_t *msg)
{
	str eval;
	str *uri;
	int ulen;
	struct lump* l;
	str out;

	if(!((get_cseq(msg)->method_id)&(METHOD_REFER)))
		return 0;

	if(parse_refer_to_header(msg)==-1)
	{
		LM_DBG("no Refer-To header\n");
		return 0;
	}
	if(msg->refer_to==NULL || get_refer_to(msg)==NULL)
	{
		LM_DBG("Refer-To header not found\n");
		return 0;
	}

	uri = &(get_refer_to(msg)->uri);
	if(th_get_uri_param_value(uri, &th_uparam_name, &eval)<0
			|| eval.len<=0)
		return -1;

	out.s = th_mask_decode(eval.s, eval.len,
				&th_uparam_prefix, 0, &out.len);
	if(out.s==NULL)
	{
		LM_ERR("cannot decode r-uri\n");
		return -1;
	}

	LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
	for(ulen=0; ulen<uri->len; ulen++)
	{
		if(uri->s[ulen]=='?')
			break;
	}

	l=del_lump(msg, uri->s-msg->buf, ulen, 0);
	if (l==0)
	{
		LM_ERR("failed deleting r-uri\n");
		pkg_free(out.s);
		return -1;
	}
	if (insert_new_lump_after(l, out.s, out.len, 0)==0)
	{
		LM_ERR("could not insert new lump\n");
		pkg_free(out.s);
		return -1;
	}

	return 0;
}
Esempio n. 18
0
int th_mask_record_route(sip_msg_t *msg)
{
	hdr_field_t *hdr;
	struct lump* l;
	int i;
	rr_t *rr;
	str out;

	if(msg->record_route==NULL)
	{
		LM_DBG("no record route header\n");
		return 0;
	}
	hdr = msg->record_route;
	i = 0;
	while(hdr!=NULL) 
	{
		if (parse_rr(hdr) < 0) 
		{
			LM_ERR("failed to parse RR\n");
			return -1;
		}

		rr =(rr_t*)hdr->parsed;
		while(rr)
		{
			i++;
			if(i!=1)
			{
				out.s = th_mask_encode(rr->nameaddr.uri.s, rr->nameaddr.uri.len,
						&th_uri_prefix, &out.len);
				if(out.s==NULL)
				{
					LM_ERR("cannot encode r-r %d\n", i);
					return -1;
				}
				l=del_lump(msg, rr->nameaddr.uri.s-msg->buf,
						rr->nameaddr.uri.len, 0);
				if (l==0)
				{
					LM_ERR("failed deleting r-r [%d]\n", i);
					pkg_free(out.s);
					return -1;
				}
				if (insert_new_lump_after(l, out.s, out.len, 0)==0){
					LM_ERR("could not insert new lump\n");
					pkg_free(out.s);
					return -1;
				}
			}
			rr = rr->next;
		}
		hdr = next_sibling_hdr(hdr);
	}

	return 0;
}
Esempio n. 19
0
static int replace_all_f(struct sip_msg* msg, regex_t* key, str* str2)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	char* begin;
	int off;
	int ret;
	int eflags;

	begin = get_header(msg);
	ret=-1; /* pessimist: we will not find any */
	eflags=0; /* match ^ at the beginning of the string*/

	while (begin<msg->buf+msg->len
				&& regexec(key, begin, 1, &pmatch, eflags)==0) {
		off=begin-msg->buf;
		if (pmatch.rm_so==-1){
			LM_ERR("offset unknown\n");
			return -1;
		}
		if (pmatch.rm_so==pmatch.rm_eo){
			LM_ERR("matched string is empty... invalid regexp?\n");
			return -1;
		}
		if ((l=del_lump(msg, pmatch.rm_so+off,
						pmatch.rm_eo-pmatch.rm_so, 0))==0) {
			LM_ERR("del_lump failed\n");
			return -1;
		}
		s=pkg_malloc(str2->len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2->s, str2->len);
		if (insert_new_lump_after(l, s, str2->len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		/* new cycle */
		begin=begin+pmatch.rm_eo;
		/* is it still a string start */
		if (*(begin-1)=='\n' || *(begin-1)=='\r')
			eflags&=~REG_NOTBOL;
		else
			eflags|=REG_NOTBOL;
		ret=1;
	} /* while found ... */
	return ret;
}
Esempio n. 20
0
int dlg_th_encode_callid(struct sip_msg *msg)
{
	struct lump *del;
	str new_callid;
	int i;

	if (msg->callid == NULL) {
		LM_ERR("Message with no callid\n");
		return -1;
	}

	new_callid.len = calc_base64_encode_len(msg->callid->body.len);
	new_callid.len += topo_hiding_prefix.len;
	new_callid.s = pkg_malloc(new_callid.len);
	if (new_callid.s==NULL) {
		LM_ERR("Failed to allocate callid len\n");
		return -1;
	}

	if (new_callid.s == NULL) {
		LM_ERR("Failed to encode callid\n");
		return -1;
	}

	memcpy(new_callid.s,topo_hiding_prefix.s,topo_hiding_prefix.len);
	for (i=0;i<msg->callid->body.len;i++)
		msg->callid->body.s[i] ^= topo_hiding_seed.s[i%topo_hiding_seed.len]; 

	base64encode((unsigned char *)(new_callid.s+topo_hiding_prefix.len),
		     (unsigned char *)(msg->callid->body.s),msg->callid->body.len);

	/* reset the callid back to original value - some might still need it ( eg. post script )
	FIXME : use bigger buffer here ? mem vs cpu */
	for (i=0;i<msg->callid->body.len;i++)
		msg->callid->body.s[i] ^= topo_hiding_seed.s[i%topo_hiding_seed.len]; 

	del=del_lump(msg, msg->callid->body.s-msg->buf, msg->callid->body.len, HDR_CALLID_T);
	if (del==NULL) {               
		LM_ERR("Failed to delete old callid\n");
		pkg_free(new_callid.s);
		return -1;
	}

	if (insert_new_lump_after(del,new_callid.s,new_callid.len,HDR_CALLID_T)==NULL) {
		LM_ERR("Failed to insert new callid\n");
		pkg_free(new_callid.s);
		return -1;
	}

	return 0;
}
Esempio n. 21
0
/* sed-perl style re: s/regular expression/replacement/flags */
static int subst_body_f(struct sip_msg* msg, char*  subst, char* ignored)
{
	struct lump* l;
	struct replace_lst* lst;
	struct replace_lst* rpl;
	char* begin;
	struct subst_expr* se;
	int off;
	int ret;
	int nmatches;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	se=(struct subst_expr*)subst;
	begin=body.s;

	off=begin-msg->buf;
	ret=-1;
	if ((lst=subst_run(se, begin, msg, &nmatches))==0)
		goto error; /* not found */
	for (rpl=lst; rpl; rpl=rpl->next){
		LM_DBG("%s replacing at offset %d [%.*s] with [%.*s]\n",
				exports.name, rpl->offset+off,
				rpl->size, rpl->offset+off+msg->buf,
				rpl->rpl.len, rpl->rpl.s);
		if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
			goto error;
		/* hack to avoid re-copying rpl, possible because both
		 * replace_lst & lumps use pkg_malloc */
		if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
			LM_ERR("%s could not insert new lump\n",
					exports.name);
			goto error;
		}
		/* hack continued: set rpl.s to 0 so that replace_lst_free will
		 * not free it */
		rpl->rpl.s=0;
		rpl->rpl.len=0;
	}
	ret=1;
error:
	LM_DBG("lst was %p\n", lst);
	if (lst) replace_lst_free(lst);
	if (nmatches<0)
		LM_ERR("%s subst_run failed\n", exports.name);
	return ret;
}
Esempio n. 22
0
int th_unmask_ruri(sip_msg_t *msg)
{
	str eval;
	struct lump* l;
	str out;

	/* Do nothing if ruri is not encoded */
	if (th_uri_prefix_checks && ((REQ_LINE(msg).uri.len<th_uri_prefix.len) ||
			(strncasecmp(REQ_LINE(msg).uri.s, th_uri_prefix.s,
						th_uri_prefix.len)!=0)))
	{
		LM_DBG("ruri [%.*s] is not encoded",REQ_LINE(msg).uri.len,REQ_LINE(msg).uri.s);
		return 0;
	}

	if(th_get_uri_param_value(&REQ_LINE(msg).uri, &th_uparam_name, &eval)<0
			|| eval.len<=0) {
		LM_DBG("no uri param [%.*s] in [%.*s]\n",
				th_uparam_name.len, th_uparam_name.s,
				REQ_LINE(msg).uri.len,REQ_LINE(msg).uri.s);
		return -1;
	}

	out.s = th_mask_decode(eval.s, eval.len,
				&th_uparam_prefix, 0, &out.len);
	if(out.s==NULL)
	{
		LM_ERR("cannot decode r-uri [%.*s]\n",
				REQ_LINE(msg).uri.len,REQ_LINE(msg).uri.s);
		return -1;
	}

	LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
	l=del_lump(msg, REQ_LINE(msg).uri.s-msg->buf, REQ_LINE(msg).uri.len, 0);
	if (l==0)
	{
		LM_ERR("failed deleting r-uri\n");
		pkg_free(out.s);
		return -1;
	}
	if (insert_new_lump_after(l, out.s, out.len, 0)==0)
	{
		LM_ERR("could not insert new lump\n");
		pkg_free(out.s);
		return -1;
	}

	return 0;
}
Esempio n. 23
0
static int replace_all_f(struct sip_msg* msg, char* key, char* str)
{


	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int len;
	char* begin;
	int off;
	int ret;
	int eflags;

	begin=get_header(msg); /* msg->orig previously .. uri problems */
	ret=-1; /* pessimist: we will not find any */
	len=strlen(str);
	eflags=0; /* match ^ at the beginning of the string*/

	while (begin<msg->buf+msg->len 
				&& regexec((regex_t*) key, begin, 1, &pmatch, eflags)==0) {
		off=begin-msg->buf;
		/* change eflags, not to match any more at string start */
		eflags|=REG_NOTBOL;
		if (pmatch.rm_so==-1){
			LOG(L_ERR, "ERROR: replace_all_f: offset unknown\n");
			return -1;
		}
		if ((l=del_lump(msg, pmatch.rm_so+off,
						pmatch.rm_eo-pmatch.rm_so, 0))==0) {
			LOG(L_ERR, "ERROR: replace_all_f: del_lump failed\n");
			return -1;
		}
		s=pkg_malloc(len);
		if (s==0){
			LOG(L_ERR, "ERROR: replace_f: mem. allocation failure\n");
			return -1;
		}
		memcpy(s, str, len); 
		if (insert_new_lump_after(l, s, len, 0)==0){
			LOG(L_ERR, "ERROR: could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		/* new cycle */
		begin=begin+pmatch.rm_eo;
		ret=1;
	} /* while found ... */
	return ret;
}
Esempio n. 24
0
int th_mask_via(sip_msg_t *msg)
{
	hdr_field_t *hdr;
	struct via_body *via;
	struct lump* l;
	int i;
	str out;
	int vlen;

	i=0;
	for(hdr=msg->h_via1; hdr; hdr=next_sibling_hdr(hdr))
	{
		for(via=(struct via_body*)hdr->parsed; via; via=via->next)
		{
			i++;
			LM_DBG("=======via[%d]\n", i);
			LM_DBG("hdr: [%.*s]\n", via->hdr.len, via->hdr.s);
			vlen = th_skip_rw(via->name.s, via->bsize);
			LM_DBG("body: %d: [%.*s]\n", vlen, vlen, via->name.s);
			if(i!=1)
			{
				out.s = th_mask_encode(via->name.s, vlen, &th_via_prefix,
						&out.len);
				if(out.s==NULL)
				{
					LM_ERR("cannot encode via %d\n", i);
					return -1;
				}
					
				LM_DBG("+body: %d: [%.*s]\n", out.len, out.len, out.s);
				l=del_lump(msg, via->name.s-msg->buf, vlen, 0);
				if (l==0)
				{
					LM_ERR("failed deleting via [%d]\n", i);
					pkg_free(out.s);
					return -1;
				}
				if (insert_new_lump_after(l, out.s, out.len, 0)==0){
					LM_ERR("could not insert new lump\n");
					pkg_free(out.s);
					return -1;
				}
			}
		}
	}
	return 0;
}
Esempio n. 25
0
static int insert_via_lump(struct sip_msg* msg, char* via, int via_len)
{
	struct lump* anchor;
	
	anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, HDR_VIA_T);
	if (anchor == 0) {
		ERR("Unable to create anchor\n");
		return -1;
	}

	if (insert_new_lump_after(anchor, via, via_len, HDR_VIA_T) == 0) {
		ERR("Unable to insert via lump\n");
		return -1;
	}

	return 0;	
}
Esempio n. 26
0
/*
 * Create an AVP to be used by registrar with the source IP and port
 * of the REGISTER
 */
static int
fix_nated_register_f(struct sip_msg* msg, char* str1, char* str2)
{
	contact_t* c;
	struct lump* anchor;
	char* param;
	str uri;

	if (create_rcv_uri(&uri, msg) < 0) {
		return -1;
	}

	if (contact_iterator(&c, msg, 0) < 0) {
		return -1;
	}

	while(c) {
		param = (char*)pkg_malloc(RECEIVED_LEN + 2 + uri.len);
		if (!param) {
			ERR("No memory left\n");
			return -1;
		}
		memcpy(param, RECEIVED, RECEIVED_LEN);
		param[RECEIVED_LEN] = '\"';
		memcpy(param + RECEIVED_LEN + 1, uri.s, uri.len);
		param[RECEIVED_LEN + 1 + uri.len] = '\"';

		anchor = anchor_lump(msg, c->name.s + c->len - msg->buf, 0, 0);
		if (anchor == NULL) {
			ERR("anchor_lump failed\n");
			return -1;
		}

		if (insert_new_lump_after(anchor, param, RECEIVED_LEN + 1 + uri.len + 1, 0) == 0) {
			ERR("insert_new_lump_after failed\n");
			pkg_free(param);
			return -1;
		}

		if (contact_iterator(&c, msg, c) < 0) {
			return -1;
		}
	}

	return 1;
}
Esempio n. 27
0
int th_unmask_callid(sip_msg_t *msg)
{
	struct lump* l;
	str out;

	if(th_param_mask_callid==0)
		return 0;

	if(msg->callid==NULL)
	{
		LM_ERR("cannot get Call-Id header\n");
		return -1;
	}

	/* Do nothing if call-id is not encoded */
	if ((msg->callid->body.len<th_callid_prefix.len) ||
			(strncasecmp(msg->callid->body.s,th_callid_prefix.s,th_callid_prefix.len)!=0))
	{
		LM_DBG("call-id [%.*s] not encoded",msg->callid->body.len,msg->callid->body.s);
		return 0;
	}

	out.s = th_mask_decode(msg->callid->body.s, msg->callid->body.len,
					&th_callid_prefix, 0, &out.len);
	if(out.s==NULL)
	{
		LM_ERR("cannot decode callid\n");
		return -1;
	}

	l=del_lump(msg, msg->callid->body.s-msg->buf, msg->callid->body.len, 0);
	if (l==0)
	{
		LM_ERR("failed deleting callid\n");
		pkg_free(out.s);
		return -1;
	}
	if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
		LM_ERR("could not insert new lump\n");
		pkg_free(out.s);
		return -1;
	}

	return 0;
}
Esempio n. 28
0
/* sed-perl style re: s/regular expression/replacement/flags */
static int subst_f(struct sip_msg* msg, char*  subst, char* ignored)
{
	struct lump* l;
	struct replace_lst* lst;
	struct replace_lst* rpl;
	char* begin;
	struct subst_expr* se;
	int off;
	int ret;
	int nmatches;
	
	se=(struct subst_expr*)subst;
	begin=get_header(msg);  /* start after first line to avoid replacing
							   the uri */
	off=begin-msg->buf;
	ret=-1;
	if ((lst=subst_run(se, begin, msg, &nmatches))==0)
		goto error; /* not found */
	for (rpl=lst; rpl; rpl=rpl->next){
		DBG(" %s: subst_f: replacing at offset %d [%.*s] with [%.*s]\n",
				exports.name, rpl->offset+off,
				rpl->size, rpl->offset+off+msg->buf,
				rpl->rpl.len, rpl->rpl.s);
		if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
			goto error;
		/* hack to avoid re-copying rpl, possible because both 
		 * replace_lst & lumps use pkg_malloc */
		if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
			LOG(L_ERR, "ERROR: %s: subst_f: could not insert new lump\n",
					exports.name);
			goto error;
		}
		/* hack continued: set rpl.s to 0 so that replace_lst_free will
		 * not free it */
		rpl->rpl.s=0;
		rpl->rpl.len=0;
	}
	ret=1;
error:
	DBG("subst_f: lst was %p\n", lst);
	if (lst) replace_lst_free(lst);
	if (nmatches<0)
		LOG(L_ERR, "ERROR: %s: subst_run failed\n", exports.name);
	return ret;
}
Esempio n. 29
0
int th_add_via_cookie(sip_msg_t *msg, struct via_body *via)
{
	struct lump* l;
	int viap;
	str out;

	if (via->params.s) {
		viap = via->params.s - via->hdr.s - 1;
	} else {
		if (via->host.s) {
			viap = via->host.s - via->hdr.s + via->host.len;
		} else {
			LM_ERR("no via parameter and no via host, can't insert cookie\n");
			return -1;
		}
		if (via->port!=0)
			viap += via->port_str.len + 1; /* +1 for ':'*/
	}
	l = anchor_lump(msg, via->hdr.s - msg->buf + viap, 0, 0);
	if (l==0)
	{
		LM_ERR("failed adding cookie to via [%p]\n", via);
		return -1;
	}

	out.len = 1+th_cookie_name.len+1+th_cookie_value.len+1;
	out.s = (char*)pkg_malloc(out.len+1);
	if(out.s==0)
	{
		LM_ERR("no pkg memory\n");
		return -1;
	}
	out.s[0] = ';';
	memcpy(out.s+1, th_cookie_name.s, th_cookie_name.len);
	out.s[th_cookie_name.len+1]='=';
	memcpy(out.s+th_cookie_name.len+2, th_cookie_value.s, th_cookie_value.len);
	out.s[out.len-1] = 'v';
	out.s[out.len] = '\0';
	if (insert_new_lump_after(l, out.s, out.len, 0)==0){
		LM_ERR("could not insert new lump!\n");
		pkg_free(out.s);
		return -1;
	}
	return 0;
}
Esempio n. 30
0
int dlg_th_decode_callid(struct sip_msg *msg)
{
	struct lump *del;
	str new_callid;
	int i,max_size;

	if (msg->callid == NULL) {
		LM_ERR("Message with no callid\n");
		return -1;
	}

	max_size = calc_max_base64_decode_len(msg->callid->body.len - topo_hiding_prefix.len);
	new_callid.s = pkg_malloc(max_size);
	if (new_callid.s==NULL) {
		LM_ERR("No more pkg\n");
		return -1;
	}
		
	new_callid.len = base64decode((unsigned char *)(new_callid.s),
			(unsigned char *)(msg->callid->body.s + topo_hiding_prefix.len),
			msg->callid->body.len - topo_hiding_prefix.len);
	for (i=0;i<new_callid.len;i++)
		new_callid.s[i] ^= topo_hiding_seed.s[i%topo_hiding_seed.len]; 

	del=del_lump(msg, msg->callid->body.s-msg->buf, msg->callid->body.len, HDR_CALLID_T);
	if (del==NULL) {               
		LM_ERR("Failed to delete old callid\n");
		pkg_free(new_callid.s);
		return -1;
	}

	if (insert_new_lump_after(del,new_callid.s,new_callid.len,HDR_CALLID_T)==NULL) {
		LM_ERR("Failed to insert new callid\n");
		pkg_free(new_callid.s);
		return -1;
	}

	return 0;

	return 0;
}