Esempio n. 1
0
/**
 * Checks if Session-Expires value is over Min_SE local policy
 * @param msg - the initial request
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not
*/
int S_check_session_expires(struct sip_msg* msg, char* str1, char* str2)
{
	time_t t_time;
	time_t min_se_time = 0;
	str ses_exp = {0,0};
 	str min_se = {0,0};
	str new_min_se = {0,0};
	str new_ses_exp = {0,0};
	struct hdr_field *h_se, *h_min_se;
	str refresher;

	ses_exp = cscf_get_session_expires_body(msg, &h_se);
	t_time = cscf_get_session_expires(ses_exp, &refresher);
	
	if (!t_time || t_time >= scscf_min_se)
		return CSCF_RETURN_TRUE;
	if (!supports_extension(msg, &str_ext_timer)) //does not suports timer extension
	{
		//add Min-SE header with its minimum interval
		min_se = cscf_get_min_se(msg, &h_min_se);
		if (min_se.len) {
			strtotime(min_se, min_se_time);
			if (min_se_time < scscf_min_se)
				cscf_del_header(msg, h_min_se);
			else
				return CSCF_RETURN_TRUE;
		}
		new_min_se.len = 11/*int value*/ + str_min_se.len+3;
		new_min_se.s = pkg_malloc(new_min_se.len+1);
		if (!new_min_se.s) {
			LOG(L_ERR,"ERR:"M_NAME":S_check_session_expires: Error allocating %d bytes\n",new_min_se.len);
			goto error;
		}
		new_min_se.len = snprintf(new_min_se.s, new_min_se.len, "%.*s %d\r\n",str_min_se.len, str_min_se.s, scscf_min_se);
		min_se_time = scscf_min_se;
		cscf_add_header(msg, &new_min_se, HDR_OTHER_T);
		if (t_time < scscf_min_se) {
			cscf_del_header(msg, h_se);
			new_ses_exp.len = 11 + str_se.len+3;
			new_ses_exp.s = pkg_malloc(new_ses_exp.len+1);
			if (!new_ses_exp.s) {
				LOG(L_ERR,"ERR:"M_NAME":S_check_session_expires: Error allocating %d bytes\n",new_ses_exp.len);
				goto error;
			}
			new_ses_exp.len = snprintf(new_ses_exp.s, new_ses_exp.len, "%.*s %d\r\n",str_se.len, str_se.s, scscf_min_se);
			t_time = scscf_min_se;
			cscf_add_header(msg, &new_ses_exp, HDR_OTHER_T);
		}
		return CSCF_RETURN_TRUE;
	}
error:
	if (new_min_se.s) pkg_free(new_min_se.s);
	if (new_ses_exp.s) pkg_free(new_ses_exp.s);
	return CSCF_RETURN_FALSE;
}		
Esempio n. 2
0
/**
 * Look for Security-Verify and delete it if found.
 * @param msg - the SIP message to add to
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not found or #CSCF_RETURN_FALSE on error
 */
int P_remove_security_verify(struct sip_msg *msg,char *str1,char*str2)
{
	struct hdr_field *hdr=0;	

	for(hdr=cscf_get_next_header(msg,s_security_verify,0);hdr;hdr=cscf_get_next_header(msg,s_security_verify,hdr)){		
		if (!cscf_del_header(msg,hdr)){
			LOG(L_INFO,"INF:"M_NAME":P_remove_security_verify: Error dropping Security-Client header.\n");		
			return CSCF_RETURN_ERROR; 
		}
	}
	return CSCF_RETURN_TRUE;
}
Esempio n. 3
0
/**
 * Applies Privacy for P-Asserted-Identity.
 * @param msg - the SIP message
 * @returns #CSCF_RETURN_TRUE if privacy applied or #CSCF_RETURN_FALSE if not
 */
int apply_privacy_id(struct sip_msg* msg){
	struct hdr_field *hdr;

	LOG(L_DBG, "DBG:"M_NAME": apply_privacy_id\n");
	hdr = cscf_get_next_header(msg,asserted_identity,NULL);
	if (!hdr) return CSCF_RETURN_FALSE;
	do {
		cscf_del_header(msg,hdr);
		hdr=cscf_get_next_header(msg,asserted_identity,hdr);
	} while (hdr);

	return CSCF_RETURN_TRUE;
}
Esempio n. 4
0
/**
 * Remove from <str1> headers the <str2> tag
 * \note Does not work if you call it multiple times for the same hdr_name!
 * \note Because of the note above, this needs a fix to accept multiple tags in the str2 parameter!
 * @param msg - SIP Request
 * @param str1 - the header to remove from
 * @param str2 - the tag to remove
 * @returns #CSCF_RETURN_TRUE if removed, #CSCF_RETURN_FALSE if no changes required or #CSCF_RETURN_FALSE on error
 */
int P_remove_header_tag(struct sip_msg *msg,char *str1, char *str2)
{
	str hdr_name,tag,x,y;
	struct hdr_field *hdr;
	char *c;
	int found,i,j,changed=0;
	
	hdr_name.s = str1;
	hdr_name.len = strlen(str1);

	tag.s = str2;
	tag.len = strlen(str2);
	
	hdr = cscf_get_header(msg,hdr_name);
	while (hdr){
		/* get the original body */
		x = hdr->body;
		LOG(L_INFO,"DBG:"M_NAME":P_remove_header_tag(): Original <%.*s> -> <%.*s>\n",
			hdr_name.len,hdr_name.s,x.len,x.s);
		
		/* duplicate the original body */
		x.len++;
		STR_PKG_DUP(y,x,"P_remove_header_tag");
		if (!y.s) goto error;
		y.len--;
		y.s[y.len]=0;
		
		/* look for occurences of tag and overwrite with \0 */
		found=0;
		c = strtok(y.s," \t\r\n,");
		while (c){
			if (strlen(c)==tag.len && strncasecmp(c,tag.s,tag.len)==0){
				found++;
				memset(c,0,tag.len);
			}	
			c = strtok(0," \t\r\n,");
		}
		
		/* if not found just skip to next header */
		if (!found) goto next;
				
		/* compact the remaining tags by removing the \0 */		
		for(i=0,j=0;i<y.len;i++)
			if (y.s[i]!=0){ 
				y.s[j++]=y.s[i];
			} else {
				if (j!=0) y.s[j++]=',';
				while(i+1<y.len && y.s[i+1]==0)
					i++;
			}
		y.len = j;
		if (y.s[y.len-1]==',') y.len--;

		LOG(L_INFO,"DBG:"M_NAME":P_remove_header_tag(): Modified <%.*s> -> <%.*s>\n",
			hdr_name.len,hdr_name.s,y.len,y.s);

		/* write the changes */
		if (y.len){
			/* replace just the content */
			if (!cscf_replace_string(msg,x,y)){
				LOG(L_ERR,"ERR:"M_NAME":P_remove_header_tag(): Error replacing string!\n");
				if (y.s) pkg_free(y.s);
				goto error;
			}
		}else{
			/* remove the whole header */
			if (y.s) pkg_free(y.s);
			if (!cscf_del_header(msg,hdr)){
				LOG(L_ERR,"ERR:"M_NAME":P_remove_header_tag(): Error removing the whole header!\n");
				goto error;
			}
		}
		changed++;
		
next:
		hdr = cscf_get_next_header(msg,hdr_name,hdr);
	}	

	return changed?CSCF_RETURN_TRUE:CSCF_RETURN_FALSE;
error:
out_of_memory:
	return CSCF_RETURN_ERROR;
}
Esempio n. 5
0
/**
 * Updates dialog on reply message
 * @param msg - the SIP message 
 * @param d - dialog to modify
 * @returns 1 on success or 0 on error
 */
int update_dialog_on_reply(struct sip_msg *msg, s_dialog *d)
{
	struct hdr_field *h_req;
	struct hdr_field *h=0;
	int res=0;
	time_t t_time=0;
	str ses_exp = {0,0};
	str refresher = {0,0};
	str new_ses_exp = {0,0};
	str new_ext = {0,0};
	int expires = 0;

	ses_exp = cscf_get_session_expires_body(msg, &h);
	t_time = cscf_get_session_expires(ses_exp, &refresher);
	if (!t_time) //i.e not session-expires header in response
	{
		if (!d->uac_supp_timer || !d->lr_session_expires)
		{
			expires = cscf_get_expires_hdr(msg,0);
			if (expires >= 0)
			{
			     d->expires = d_act_time()+expires;
			}
			else
			{
			     d->expires = d_act_time()+scscf_dialogs_expiration_time;
			}
		}
		else// uac supports timer, but no session-expires header found in response
		{
			d->expires = d_act_time()+d->lr_session_expires;
			
			new_ses_exp.len = 11/*int value*/ + str_se.len+s_refresher.len+8;
			new_ses_exp.s = pkg_malloc(new_ses_exp.len+1);
			if (!new_ses_exp.s) {
				LOG(L_ERR,"ERR:"M_NAME":update_dialog_on_reply: Error allocating %d bytes\n",new_ses_exp.len);
				goto error;
			}
			new_ses_exp.len = snprintf(new_ses_exp.s, new_ses_exp.len, "%.*s %d; %.*suac\r\n",str_se.len, str_se.s, (int)d->lr_session_expires ,s_refresher.len, s_refresher.s);
			cscf_add_header(msg, &new_ses_exp, HDR_OTHER_T);
			if (!requires_extension(msg, &str_ext_timer)) //must have require timer extenstion
			{
				/* walk through all Require headers to find first require header*/
				res = parse_headers(msg, HDR_EOH_F, 0);
				if (res == -1) {
					ERR("Error while parsing headers (%d)\n", res);
					return 0; /* what to return here ? */
				}
				
				h_req = msg->require;
				while (h_req) {
					if (h_req->type == HDR_REQUIRE_T) {
						if (h_req->body.s[new_ext.len-1]=='\n')
						{
							new_ext.len = str_require.len + 1/* */+h_req->body.len + 7;/*, timer*/
							new_ext.s = pkg_malloc(new_ext.len);
							if (!new_ext.s) {
								LOG(L_ERR,"ERR:"M_NAME":update_dialog_on_reply: Error allocating %d bytes\n",new_ext.len);
								goto error;
							}			
							new_ext.len = snprintf(new_ext.s, str_require.len, "%.*s %.*s, timer\r\n", str_require.len, str_require.s, h_req->body.len-2, h_req->body.s);
						}
						else
						{
							new_ext.len = str_require.len + 1/*space*/ + h_req->body.len + 9;/*, timer\r\n*/
							new_ext.s = pkg_malloc(new_ext.len);
							if (!new_ext.s) {
								LOG(L_ERR,"ERR:"M_NAME":update_dialog_on_reply: Error allocating %d bytes\n",new_ext.len);
								goto error;
							}			
							new_ext.len = snprintf(new_ext.s, str_require.len, "%.*s %.*s, timer\r\n", str_require.len, str_require.s, h_req->body.len, h_req->body.s);
						}
						cscf_del_header(msg, h_req);
						cscf_add_header(msg, &new_ext, HDR_REQUIRE_T);
						break;
					}
					h_req = h_req->next;
				}
			}
		}
	}
	else{
		d->expires = d_act_time() + t_time;
		d->lr_session_expires = t_time;
	}
	return 1;
error:
	if (new_ses_exp.s) pkg_free(new_ses_exp.s);
	if (new_ext.s) pkg_free(new_ext.s);
	return 0;	
}