Esempio n. 1
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;
}
Esempio n. 2
0
static struct rdata* deserialize_dns_rdata(char *buff,int buf_len,int do_decoding)
{
	unsigned char *p;
	int max_len=0,actual_len=0,entry_len=0;
	struct rdata *head,*it,**last;
	struct naptr_rdata *naptr_rd;
	struct srv_rdata *srv_rd;
	struct txt_rdata *txt_rd;
	struct ebl_rdata *ebl_rd;

	head=it=NULL;
	last=&head;	

	if (do_decoding) {
		max_len = calc_max_base64_decode_len(buf_len);
	} else {
		max_len = buf_len;
	}

	if (dec_rdata_buf == NULL || max_len > dec_rdata_buf_len) {
		/* realloc buff if not enough space */
		dec_rdata_buf = pkg_realloc(dec_rdata_buf,max_len);	
		if (dec_rdata_buf == NULL) {
			LM_ERR("No more pkg\n");
			return NULL;				
		}
		dec_rdata_buf_len = max_len;
	}

	if (do_decoding) {
		/* decode base64 buf */
		actual_len = base64decode(dec_rdata_buf,(unsigned char *)buff,buf_len);	
		p = dec_rdata_buf;
	} else {
		memcpy(dec_rdata_buf,buff,buf_len);
		actual_len = buf_len;
		p = dec_rdata_buf;
	}

	while ( p < dec_rdata_buf+actual_len) {
		it = pkg_malloc(sizeof(struct rdata));		
		if (it == 0) {
			LM_ERR("no more pkg mem\n");
			goto it_alloc_error;
		}

		/* copy type, class & ttl */
		memcpy(it,p,rdata_struct_len);
		p+=rdata_struct_len;			
		it->next=0;
		it->rdata=0;

		switch (it->type) {
			case T_A:
				it->rdata = pkg_malloc(sizeof(struct a_rdata)); 
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				memcpy(p,it->rdata,sizeof(struct a_rdata));
				p+=sizeof(struct a_rdata);	
				*last=it;
				last=&(it->next);
				break;	
			case T_AAAA:
				it->rdata = pkg_malloc(sizeof(struct aaaa_rdata)); 
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				memcpy(p,it->rdata,sizeof(struct aaaa_rdata));
				p+=sizeof(struct aaaa_rdata);	
				*last=it;
				last=&(it->next);
				break;	
			case T_CNAME:
				it->rdata = pkg_malloc(sizeof(struct cname_rdata));	
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}	
				memcpy(&entry_len,p,sizeof(int));
				p+=sizeof(int);	
				memcpy(((struct cname_rdata*)it->rdata)->name,
					p,entry_len+1);
				p+=entry_len+1;		
				*last=it;
				last=&(it->next);
				break;
			case T_NAPTR:
				it->rdata = pkg_malloc(sizeof(struct naptr_rdata));
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				naptr_rd = (struct naptr_rdata*)it->rdata;
				memcpy(naptr_rd,p,2*sizeof(unsigned short) + 
					sizeof(unsigned int));
				p+=2*sizeof(unsigned short) + sizeof(unsigned int);
				memcpy(naptr_rd->flags,p,naptr_rd->flags_len+1);
				p+=naptr_rd->flags_len+1;
				memcpy(&naptr_rd->services_len,p,sizeof(unsigned int));
				p+=sizeof(unsigned int);
				memcpy(naptr_rd->services,p,naptr_rd->services_len+1);
				p+=naptr_rd->services_len+1;
				memcpy(&naptr_rd->regexp_len,p,sizeof(unsigned int));
				p+=sizeof(unsigned int);
				memcpy(naptr_rd->regexp,p,naptr_rd->regexp_len+1);
				p+=naptr_rd->regexp_len+1;
				memcpy(&naptr_rd->repl_len,p,sizeof(unsigned int));
				p+=sizeof(unsigned int);
				memcpy(naptr_rd->repl,p,naptr_rd->repl_len+1);
				p+=naptr_rd->repl_len+1;
				*last=it;
				last=&(it->next);
				break;
			case T_SRV:
				it->rdata = pkg_malloc(sizeof(struct srv_rdata));
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				srv_rd = (struct srv_rdata*)it->rdata;
				memcpy(srv_rd,p,4*sizeof(unsigned short) + 
					sizeof(unsigned int));
				p+=4*sizeof(unsigned short) + sizeof(unsigned int);
				memcpy(srv_rd->name,p,srv_rd->name_len+1);
				p+=srv_rd->name_len+1;
				*last=it;
				last=&(it->next);
				break;
			case T_TXT:
				it->rdata = pkg_malloc(sizeof(struct txt_rdata));
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				txt_rd = (struct txt_rdata*)it->rdata;
				memcpy(&entry_len,p,sizeof(int));
				p+=sizeof(int);	
				memcpy(txt_rd->txt,p,entry_len+1);
				p+=entry_len+1;		
				*last=it;
				last=&(it->next);
				break;
			case T_EBL:
				it->rdata = pkg_malloc(sizeof(struct ebl_rdata));
				if (it->rdata == 0) {
					LM_ERR("no more pkg\n");
					goto rdata_alloc_error;
				}
				ebl_rd = (struct ebl_rdata*)it->rdata;
				memcpy(ebl_rd,p,sizeof(unsigned char) + 
					sizeof(unsigned int));	
				p+=sizeof(unsigned char)+sizeof(unsigned int);	
				memcpy(ebl_rd->separator,p,ebl_rd->separator_len+1);
				p+=ebl_rd->separator_len+1;
				memcpy(&ebl_rd->apex_len,p,sizeof(unsigned int));
				p+=sizeof(unsigned int);
				memcpy(ebl_rd->apex,p,ebl_rd->apex_len+1);
				p+=ebl_rd->apex_len+1;
				*last=it;
				last=&(it->next);
				break;
		}
	}

	return head;

rdata_alloc_error:
	if (it) 
		pkg_free(it);
it_alloc_error:
	if (head)
		free_rdata_list(head);
	return NULL;
}
Esempio n. 3
0
static struct hostent* deserialize_he_rdata(char *buff,int buf_len,int do_decoding)
{
	char **ap,**hap;
	unsigned char *p;
	int max_len=0;
	int i,alias_no=0,addr_no=0,len=0;
	
	/* max estimation of needed buffer */
	if (do_decoding) {
		max_len=calc_max_base64_decode_len(buf_len);
	} else {
		max_len = buf_len;
	}

	if (dec_he_buf == NULL || max_len > dec_he_buf_len) {
		/* realloc buff if not enough space */
		dec_he_buf = pkg_realloc(dec_he_buf,max_len);	
		if (dec_he_buf == NULL) {
			LM_ERR("No more pkg\n");
			return NULL;				
		}
		dec_he_buf_len = max_len;
	}

	/* set pointer in dec_global_he */
	ap = host_aliases;
	*ap = NULL;
	dec_global_he.h_aliases = host_aliases;
	hap = h_addr_ptrs;
	*hap = NULL;
	dec_global_he.h_addr_list = h_addr_ptrs;
	
	if (do_decoding) {
		/* decode base64 buf */
		base64decode(dec_he_buf,(unsigned char *)buff,buf_len);
		p = dec_he_buf;
	} else {
		memcpy(dec_he_buf,buff,buf_len);
		p = dec_he_buf;
	}

	/* set address type & length */
	memcpy(&dec_global_he.h_addrtype,p,sizeof(int));
	p+=sizeof(int);
	if (dec_global_he.h_addrtype == AF_INET)
		dec_global_he.h_length=4;
	else
		dec_global_he.h_length=16;

	/* set name */
	memcpy(&len,p,sizeof(int));
	p+=sizeof(int);
	dec_global_he.h_name = (char *)p;
	p+=len;

	/* get number of aliases */
	memcpy(&alias_no,p,sizeof(int));
	p+=sizeof(int);

	for (i=0;i<alias_no;i++) {
		/* get alias length, set pointer and skip over length */
		memcpy(&len,p,sizeof(int));
		p+=sizeof(int);
		*ap++ = (char *)p;
		p+=len;		
	}

	/* get number of addresses */
	memcpy(&addr_no,p,sizeof(int));	
	p+=sizeof(int);

	for (i=0;i<addr_no;i++) {
		/* set pointer and skip over length */
		*hap++ = (char *)p;	
		p+=dec_global_he.h_length;
	}			
		
	return &dec_global_he;
}
Esempio n. 4
0
/*
 * Function to decompress a compressed message
 */
static int mc_decompress(struct sip_msg* msg)
{
	#define HDRS_TO_SKIP 4

	int i;
	int j;
	int rc;
	int algo=-1;
	int hdrs_algo=-1;
	int b64_required=-1;

	str msg_body;
	str msg_final;

	str b64_decode={NULL, 0};
	str hdr_b64_decode={NULL,0};
	str uncomp_body={NULL,0};
	str uncomp_hdrs={NULL,0};

	char *new_buf;

	unsigned long temp;

	/* hdr_vec allows to sort the headers. This will help skipping
		these headers when building the new message */
	struct hdr_field *hf;
	struct hdr_field *hdr_vec[HDRS_TO_SKIP];
					/*hdr_vec : 	0 Content-Length
							1 Comp-Hdrs
							2 Headers-Algo
							3 Content-Encoding*/

	memset(hdr_vec, 0, HDRS_TO_SKIP * sizeof(struct hdr_field*));

	if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
		LM_ERR("failed to parse SIP message\n");
		return -1;
	}

	/*If compressed with this module there are great chances that Content-Encoding is last*/
	hdr_vec[3] = msg->last_header;

	if (!is_content_encoding(hdr_vec[3])) {
		hdr_vec[3] = NULL;
		for (hf = msg->headers; hf; hf = hf->next) {
			if (is_content_encoding(hf)) {
				hdr_vec[3] = hf;
				continue;
			}
			if (hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, COMP_HDRS,COMP_HDRS_LEN)) {
				hdr_vec[1] = hf;
				continue;
			}

			if (hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, HDRS_ENCODING,
						sizeof(HDRS_ENCODING)-1)) {
				hdr_vec[2] = hf;
			}

			if (hdr_vec[1] && hdr_vec[2] && hdr_vec[3])
					break;
		}
	} else {
		for (hf = msg->headers; hf; hf = hf->next) {
			if (!hdr_vec[1] && hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, COMP_HDRS,COMP_HDRS_LEN)) {
				hdr_vec[1] = hf;
				continue;
			}

			if (!hdr_vec[2] && hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, HDRS_ENCODING,
						sizeof(HDRS_ENCODING)-1))
				hdr_vec[2] = hf;

			if (hdr_vec[2] && hdr_vec[3] && hdr_vec[1])
					break;
		}
	}

	/* Only if content-encoding present, Content-Length will be replaced
		with the one in the compressed body or in compressed headers*/

	if (hdr_vec[3]) {
		hdr_vec[0] = msg->content_length;
		parse_algo_hdr(hdr_vec[3], &algo, &b64_required);
	}


	if (b64_required > 0 && hdr_vec[3]) {
		msg_body.s = msg->last_header->name.s + msg->last_header->len + CRLF_LEN;
		msg_body.len = strlen(msg_body.s);

		/* Cutting CRLF'S at the end of the message */
		while (WORD(msg_body.s + msg_body.len-CRLF_LEN) == PARSE_CRLF) {
			msg_body.len -= CRLF_LEN;
		}

		if (wrap_realloc(&body_in, calc_max_base64_decode_len(msg_body.len)))
			return -1;

		b64_decode.s = body_in.s;

		b64_decode.len = base64decode((unsigned char*)b64_decode.s,
						(unsigned char*)msg_body.s,
							msg_body.len);
	} else if (hdr_vec[3]) {
		if (get_body(msg, &msg_body) < 0) {
			LM_ERR("failed to get body\n");
			return -1;
		}

		b64_decode.s = msg_body.s;
		b64_decode.len = msg_body.len;
	}

	b64_required=0;
	if (hdr_vec[2]) {
		parse_algo_hdr(hdr_vec[3], &algo, &b64_required);
	}

	if (b64_required > 0 &&  hdr_vec[1]) {
		if (wrap_realloc(&hdr_in, calc_max_base64_decode_len(hdr_vec[1]->body.len)))
			return -1;

		hdr_b64_decode.s = hdr_in.s;

		hdr_b64_decode.len = base64decode(
					(unsigned char*)hdr_b64_decode.s,
					(unsigned char*)hdr_vec[1]->body.s,
							hdr_vec[1]->body.len
					);
	} else if (hdr_vec[1]) {
		hdr_b64_decode.s = hdr_vec[1]->body.s;
		hdr_b64_decode.len = hdr_vec[1]->body.len;
	}

	switch (hdrs_algo) {
		case 0: /* deflate */
			temp = (unsigned long)BUFLEN;

			rc = uncompress((unsigned char*)hdr_buf,
					&temp,
					(unsigned char*)hdr_b64_decode.s,
					(unsigned long)hdr_b64_decode.len);

			uncomp_hdrs.s = hdr_buf;
			uncomp_hdrs.len = temp;

			if (check_zlib_rc(rc)) {
				LM_ERR("header decompression failed\n");
				return -1;
			}
			break;
		case 1: /* gzip */
			rc = gzip_uncompress(
					(unsigned char*)hdr_b64_decode.s,
					(unsigned long)hdr_b64_decode.len,
					&hdr_out,
					&temp);

			if (check_zlib_rc(rc)) {
				LM_ERR("header decompression failed\n");
				return -1;
			}

			uncomp_hdrs.s = hdr_out.s;
			uncomp_hdrs.len = temp;

			break;
		case -1:
			break;
		default:
			return -1;
	}

	switch (algo) {
		case 0: /* deflate */
			temp = (unsigned long)BUFLEN;

			rc = uncompress((unsigned char*)body_buf,
					&temp,
					(unsigned char*)b64_decode.s,
					(unsigned long)b64_decode.len);

			if (check_zlib_rc(rc)) {
				LM_ERR("body decompression failed\n");
				return -1;
			}

			uncomp_body.s = body_buf;
			uncomp_body.len = temp;

			break;
		case 1: /* gzip */
			rc = gzip_uncompress(
					(unsigned char*)b64_decode.s,
					(unsigned long)b64_decode.len,
					&body_out,
					&temp);

			if (check_zlib_rc(rc)) {
				LM_ERR("body decompression failed\n");
				return -1;
			}

			uncomp_body.s = body_out.s;
			uncomp_body.len = temp;

			break;
		case -1:
			LM_DBG("no body\n");
			break;
		default:
			LM_ERR("invalid algo\n");
			return -1;
	}

	/* Sort to have the headers in order */
	for (i = 0; i < HDRS_TO_SKIP - 1; i++) {
		for (j = i + 1; j < HDRS_TO_SKIP; j++) {
			if (!hdr_vec[j])
				continue;

			if (!hdr_vec[i] && hdr_vec[j]) {
				hdr_vec[i] = hdr_vec[j];
				hdr_vec[j] = NULL;
			}

			if ((hdr_vec[i] && hdr_vec[j]) &&
				(hdr_vec[i]->name.s > hdr_vec[j]->name.s)) {
				hf = hdr_vec[i];
				hdr_vec[i] = hdr_vec[j];
				hdr_vec[j] = hf;
			}
		}
	}

	int msg_final_len = 0;
	int msg_ptr=0;

	for ( i = 0; i < HDRS_TO_SKIP; i++) {
		if (hdr_vec[i]) {
			msg_final_len += hdr_vec[i]->name.s - (msg->buf+msg_ptr);
			msg_ptr += hdr_vec[i]->name.s+hdr_vec[i]->len - (msg->buf+msg_ptr);
		}
	}

	msg_final_len += msg->last_header->name.s + msg->last_header->len -
				(msg->buf + msg_ptr);

	if (hdrs_algo >= 0)
		msg_final_len += uncomp_hdrs.len;

	if (algo >= 0)
		msg_final_len += uncomp_body.len;
	else
		msg_final_len += strlen(msg->eoh);

	if (wrap_realloc(&buf_out, msg_final_len))
		return -1;

	msg_ptr = 0;

	msg_final.len = 0;
	msg_final.s = buf_out.s;

	for ( i = 0; i < HDRS_TO_SKIP; i++) {
		if (hdr_vec[i]) {
			wrap_copy_and_update(&msg_final.s,
					msg->buf+msg_ptr,
					hdr_vec[i]->name.s-(msg->buf+msg_ptr),
					&msg_final.len);

			msg_ptr += (hdr_vec[i]->name.s+hdr_vec[i]->len) -
					(msg->buf+msg_ptr);
		}
	}

	wrap_copy_and_update(
			&msg_final.s,
			msg->buf+msg_ptr,
			(msg->last_header->name.s+msg->last_header->len)-
							(msg->buf+msg_ptr),
			&msg_final.len
		);

	if (hdrs_algo >= 0) {
		wrap_copy_and_update(&msg_final.s, uncomp_hdrs.s,
					uncomp_hdrs.len,&msg_final.len);
	}

	if (algo >= 0) {
		wrap_copy_and_update(&msg_final.s, uncomp_body.s,
					uncomp_body.len, &msg_final.len);
	} else {
		wrap_copy_and_update(&msg_final.s, msg->eoh, strlen(msg->eoh), &msg_final.len);
	}

	/* new buffer because msg_final(out_buf) will
	 * be overwritten at next iteration */
#ifdef DYN_BUF
	new_buf = pkg_malloc(msg_final.len+1);
	if (new_buf == NULL) {
		LM_ERR("no more pkg mem\n");
		return -1;
	}
#else
	new_buf = msg->buf;
#endif

	memcpy(new_buf, msg_final.s, msg_final.len);
	new_buf[msg_final.len] = '\0';

	struct sip_msg tmp;

	memcpy(&tmp, msg, sizeof(struct sip_msg));

	/*reset dst_uri and path_vec to avoid free*/
	if (msg->dst_uri.s != NULL) {
		msg->dst_uri.s = NULL;
		msg->dst_uri.len = 0;
	}
	if (msg->path_vec.s != NULL)
	{
		msg->path_vec.s = NULL;
		msg->path_vec.len = 0;
	}

	free_sip_msg(msg);
	memset(msg, 0, sizeof(struct sip_msg));

	/* restore msg fields */
	msg->id					= tmp.id;
	msg->rcv				= tmp.rcv;
	msg->set_global_address = tmp.set_global_address;
	msg->set_global_port    = tmp.set_global_port;
	msg->flags              = tmp.flags;
	msg->msg_flags          = tmp.msg_flags;
	msg->hash_index         = tmp.hash_index;
	msg->force_send_socket  = tmp.force_send_socket;
	msg->dst_uri            = tmp.dst_uri;
	msg->path_vec           = tmp.path_vec;
	/* set the new ones */
	msg->buf = new_buf;
	msg->len = msg_final.len;

	/* reparse the message */
	if (parse_msg(msg->buf, msg->len, msg) != 0)
		LM_ERR("parse_msg failed\n");

	return 1;
}