示例#1
0
文件: security.c 项目: asyn/openvims
/**
 * enforce a response coming from a UE to contain the same Via headers sent in the corresponding request
 * @param rpl - the SIP reply
 * @param str1 - not used
 * @param str2 - not used
 * @returns true if ok, false if not or error
 */
int P_enforce_via_list(struct sip_msg *rpl,char *str1, char *str2)
{
	static struct hdr_field * h = NULL;
	str hdr;

	cscf_del_all_headers(rpl, HDR_VIA_T);

	struct sip_msg *req = cscf_get_request_from_reply(rpl);
	
	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_via_list: No transactional request found.\n");
		return CSCF_RETURN_FALSE;
	
	}

	h = cscf_get_next_via_hdr(req,0);
	while (h)
	{
		hdr.len = h->body.len + via_hdr_s.len + via_hdr_e.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s)
		{
			LOG(L_ERR, "ERR:"M_NAME":P_enforce_via_list: cannot alloc bytes : %d", hdr.len);
		}
		hdr.len=0;
		STR_APPEND(hdr, via_hdr_s);
		STR_APPEND(hdr, h->body);
		STR_APPEND(hdr, via_hdr_e);
		cscf_add_header_first(rpl, &hdr, HDR_VIA_T);
		h = cscf_get_next_via_hdr(req,h);
	}
	
	return CSCF_RETURN_TRUE;
}
示例#2
0
/**
 * Check if we already did record-route
 * @param msg - the SIP message to add to
 * @param str1 - direction - "orig" or "term"
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error
 */
int S_is_record_routed(struct sip_msg *msg,char *str1,char *str2)
{
	str rr;
	str u = {0,0},scheme={0,0},scscf={0,0};
	struct hdr_field *hdr=0;
	rr_t *rr_s;
	
	enum s_dialog_direction dir = get_dialog_direction(str1);
	
	switch (dir){
		case DLG_MOBILE_ORIGINATING:
			STR_PKG_DUP(rr,scscf_record_route_mo,"pkg");
			break;
		case DLG_MOBILE_TERMINATING:
			STR_PKG_DUP(rr,scscf_record_route_mt,"pkg");
			break;
		default:
			u.s = str1;
			u.len = strlen(str1);
			if (scscf_name_str.len>4 &&
				strncasecmp(scscf_name_str.s,"sip:",4)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}else if (scscf_name_str.len>5 &&
				strncasecmp(scscf_name_str.s,"sips:",5)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}
			scscf.s = scheme.s+scheme.len;
			scscf.len = scscf_name_str.len - scheme.len;
			
			rr.len = scheme.len+u.len+1+scscf.len;
			rr.s = pkg_malloc(rr.len);
			if (!rr.s){
				LOG(L_ERR,"ERR:"M_NAME":S_record_route: error allocating %d bytes!\n",rr.len);	
				return CSCF_RETURN_BREAK;
			}
			rr.len = 0;
			STR_APPEND(rr,scheme);
			STR_APPEND(rr,u);
			rr.s[rr.len++]='@';
			STR_APPEND(rr,scscf);
	}

	for(hdr = cscf_get_next_record_route(msg,(struct hdr_field*) 0); hdr ; hdr = cscf_get_next_record_route(msg,hdr)){
		for (rr_s = (rr_t *)hdr->parsed;rr_s; rr_s = rr_s->next)
			if (rr_s->nameaddr.uri.len == rr.len &&
				strncasecmp(rr_s->nameaddr.uri.s,rr.s,rr.len)==0){
					pkg_free(rr.s);
					return CSCF_RETURN_TRUE;
				}
	}

	pkg_free(rr.s);
	return CSCF_RETURN_FALSE;
out_of_memory:
	return CSCF_RETURN_ERROR;
}
/**
 * Inserts the Route header containing the Service-Route to be enforced
 * @param msg - the SIP message to add to
 * @param str1 - the value to insert (IBCF URI here) - !!! quoted if needed
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok or #CSCF_RETURN_ERROR on error
 */
int P_route_to_IBCF(struct sip_msg *msg,char *str1,char*str2)
{
	str newuri={0,0};
	str uri;
	str x;
	int add_lr=0;
	static str lr_param={";lr",3};

	/* Get char *str1 into str uri */
	uri.s = str1;
	uri.len = strlen(str1);

	x.len = route_s.len + uri.len + route_e.len;
	/* Add ;lr if there's not in the URI */
	if (!strstr(str1,";lr")){
		add_lr=1;
		x.len+=lr_param.len;
	}

	x.s = pkg_malloc(x.len);
	if (!x.s){
		LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",x.len);
		x.len=0;
		return CSCF_RETURN_ERROR;
	}
	
	/* Get complete Route header into x */
	x.len=0;
	STR_APPEND(x,route_s);
	STR_APPEND(x,uri);
	if (add_lr)
		STR_APPEND(x,lr_param);
	STR_APPEND(x,route_e);

	/* Set dst_uri to the topmost Route URI */
	newuri.s = pkg_malloc(uri.len);
	if (!newuri.s){
		LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",uri.len);
		return CSCF_RETURN_ERROR;
	}
	newuri.len = uri.len;
	memcpy(newuri.s,uri.s,newuri.len);
	if (msg->dst_uri.s)
		pkg_free(msg->dst_uri.s);
	msg->dst_uri = newuri;

	/* Add those Route header in x into msg */
	if (cscf_add_header_first(msg,&x,HDR_ROUTE_T))
		return CSCF_RETURN_TRUE;
	else {
		LOG(L_ERR,"ERR:"M_NAME":P_route_to_IBCF: Failed to add new Route.\n");
		if (x.s) pkg_free(x.s);
		return CSCF_RETURN_ERROR;
	}

}
示例#4
0
/**
 * Record routes, with given user as parameter.
 * @param msg - the SIP message to add to
 * @param str1 - direction - "orig" or "term"
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error
 */ 
int S_record_route(struct sip_msg *msg,char *str1,char *str2)
{
	str rr={0,0};
	str u = {0,0},scheme={0,0},scscf={0,0};
	
	enum s_dialog_direction dir = get_dialog_direction(str1);
	
	switch (dir){
		case DLG_MOBILE_ORIGINATING:
			STR_PKG_DUP(rr,scscf_record_route_mo,"pkg");
			break;
		case DLG_MOBILE_TERMINATING:
			STR_PKG_DUP(rr,scscf_record_route_mt,"pkg");
			break;
		default:
			u.s = str1;
			u.len = strlen(str1);
			if (scscf_name_str.len>4 &&
				strncasecmp(scscf_name_str.s,"sip:",4)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}else if (scscf_name_str.len>5 &&
				strncasecmp(scscf_name_str.s,"sips:",5)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}
			scscf.s = scheme.s+scheme.len;
			scscf.len = scscf_name_str.len - scheme.len;
			
			rr.len = s_record_route_s.len+scheme.len+u.len+1+scscf.len+s_record_route_e.len;
			rr.s = pkg_malloc(rr.len);
			if (!rr.s){
				LOG(L_ERR,"ERR:"M_NAME":S_record_route: error allocating %d bytes!\n",rr.len);	
				return CSCF_RETURN_BREAK;
			}
			rr.len = 0;
			STR_APPEND(rr,s_record_route_s);
			STR_APPEND(rr,scheme);
			STR_APPEND(rr,u);
			rr.s[rr.len++]='@';
			STR_APPEND(rr,scscf);
			STR_APPEND(rr,s_record_route_e);					
	}
	
	if (cscf_add_header_first(msg,&rr,HDR_RECORDROUTE_T)) return CSCF_RETURN_TRUE;
	else{
		if (rr.s) pkg_free(rr.s);
		return CSCF_RETURN_BREAK;
	}
	
out_of_memory:
	return CSCF_RETURN_BREAK;	
}
/**
 * Enforce a response coming from a UE to contain the same Record Route headers sent in the
 * corresponding request.
 * @param msg - the SIP reply
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE on success, #CSCF_RETURN_ERROR on error
 */
int P_enforce_record_routes(struct sip_msg *msg,char *str1, char *str2)
{
	str hdr = {0,0};
	str rr_req = {0,0};
	struct sip_msg *req = cscf_get_request_from_reply(msg);

	LOG(L_INFO,"INF:"M_NAME":P_enforce_record_routes(): Enforcing RR in %d reply with the request ones\n",
			msg->first_line.u.reply.statuscode);

	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): No transactional request found.\n");
		return CSCF_RETURN_ERROR;
	}
	
	if(!cscf_del_all_headers(msg, HDR_RECORDROUTE_T)){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): error while deleting headers\n");
		return CSCF_RETURN_ERROR;
	}
	
	rr_req = cscf_get_record_routes(req);
	if(rr_req.len){
		hdr.len = pcscf_record_route_mt.len + s_record_route_s.len + rr_req.len+s_record_route_e.len;
		if(!(hdr.s = pkg_malloc(hdr.len))){
		    LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to allocate memory for hdr\n");
		    goto out_of_memory;
		}
		hdr.len = 0;
		STR_APPEND(hdr,pcscf_record_route_mt);
		STR_APPEND(hdr,s_record_route_s);
		STR_APPEND(hdr,rr_req);
		STR_APPEND(hdr,s_record_route_e);		
	}else{		
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to get record routes - the RR should not be empty...\n");
		// still, let it continue, maybe it was empty on purpose
		//return CSCF_RETURN_ERROR;
		STR_PKG_DUP(hdr,pcscf_record_route_mt,"pkg");
	}
	
	if(!cscf_add_header_first(msg,&hdr,HDR_RECORDROUTE_T)){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to add header\n");
		if (hdr.s) pkg_free(hdr.s);
		return CSCF_RETURN_FALSE;
	}

	return CSCF_RETURN_TRUE;
	
out_of_memory:
	return CSCF_RETURN_ERROR;
}
示例#6
0
boolean graph_write_dimacs_binary(graph_t *g, char *comment,FILE *fp) {
	char *buf;
	char *header=NULL;
	int headersize=0;
	int headerlength=0;
	int i,j;

	ASSERT((sizeof(setelement)*8)==ELEMENTSIZE);
	ASSERT(graph_test(g,NULL));
	ASSERT(fp!=NULL);

	buf=malloc(MAX(1024,g->n/8+1));
	header=malloc(1024);
	header[0]=0;
	headersize=1024;
	if (comment) {
		strcpy(buf,"c ");
		strncat(buf,comment,1000);
		strcat(buf,"\n");
		STR_APPEND(buf);
	}
	sprintf(buf,"p edge %d %d\n",g->n,graph_edge_count(g));
	STR_APPEND(buf);
	for (i=0; i < g->n; i++) {
		if (g->weights[i]!=1) {
			sprintf(buf,"n %d %d\n",i+1,g->weights[i]);
			STR_APPEND(buf);
		}
	}

	fprintf(fp,"%d\n",(int)strlen(header));
	fprintf(fp,"%s",header);
	free(header);

	for (i=0; i < g->n; i++) {
		memset(buf,0,i/8+1);
		for (j=0; j<i; j++) {
			if (GRAPH_IS_EDGE_FAST(g,i,j)) {
				buf[j/8] |= SET_BIT_MASK(7-j%8);
			}
		}
		fwrite(buf,1,i/8+1,fp);
	}
	free(buf);
	return TRUE;
}
示例#7
0
int assert_called_identity(struct sip_msg* _m, udomain_t* _d) {
	
	int ret=CSCF_RETURN_FALSE;
	str called_party_id={0,0},x={0,0};
	struct sip_msg* req;
	struct hdr_field *h=0;
		
	//get request from reply
	req = get_request_from_reply(_m);
	if (!req) {
		LM_ERR("Unable to get request from reply for REGISTER. No transaction\n");
		goto error;
	}
	
	called_party_id = cscf_get_public_identity_from_called_party_id(req, &h);
	
		
	if (!called_party_id.len){
		goto error;	
	}else{
		LM_DBG("Called Party ID from request: %.*s\n", called_party_id.len, called_party_id.s);	
		x.len = p_asserted_identity_s.len+p_asserted_identity_m.len+called_party_id.len+p_asserted_identity_e.len;
		x.s = pkg_malloc(x.len);
		if (!x.s){
			LM_ERR("P_assert_called_identity: Error allocating %d bytes\n",	x.len);
			x.len=0;
			goto error;		
		}
		x.len=0;
		STR_APPEND(x,p_asserted_identity_s);
		STR_APPEND(x,p_asserted_identity_m);
		STR_APPEND(x,called_party_id);
		STR_APPEND(x,p_asserted_identity_e);
		
		if (cscf_add_header(_m,&x,HDR_OTHER_T))
			ret = CSCF_RETURN_TRUE;
		else
		    goto error;
	}
	
	return ret;
	
error:
	ret=CSCF_RETURN_FALSE;
	return ret;
}
/* build the extra headers for the OPTIONS reply : containing Content-type and ESQK
 * @param headers -  the resulting string will be stored there
 * @param d - the user data cell
 * @return 0 if ok, -1 if error
 */
int get_options_resp_headers(str * headers, user_d * d){

	if(!headers || !d){
		LOG(L_ERR, "ERR:"M_NAME":get_options_resp_headers: invalid parameters\n");
		return -1;
	}
	
	if(!d->esqk.s || !d->esqk.len){
		LOG(L_ERR, "BUG:"M_NAME":get_options_resp_headers: esqk not well set");
		return -1;
	}
	
	headers->len = esqk_hdr_s.len + d->esqk.len + esqk_hdr_e.len + content_type_hdr.len +
			psap_uri_hdr_s.len+d->psap_uri.len+esqk_hdr_e.len+1;
	headers->s = pkg_malloc(headers->len* sizeof(char));
	if(!headers->s){
		LOG(L_ERR, "ERR:"M_NAME":get_options_resp_headers: out of pkg memory\n");
		return -1;
	}

	headers->len = 0;
	STR_APPEND(*headers, esqk_hdr_s);
	STR_APPEND(*headers, d->esqk);
	STR_APPEND(*headers, esqk_hdr_e);
	STR_APPEND(*headers, psap_uri_hdr_s);
	STR_APPEND(*headers, d->psap_uri);
	STR_APPEND(*headers, esqk_hdr_e);
	if(d->loc && d->locsip_loc)
		STR_APPEND(*headers, content_type_hdr);
	headers->s[headers->len] = '\0';

	LOG(L_DBG, "DBG:"M_NAME":get_options_resp_headers: headers are: %s\n", headers->s);

	return 0;
}
/**
 * Replies to a SUBSCRIBE and also adds the need headers.
 * Path for example.
 * @param msg - the SIP SUBSCRIBE message
 * @param code - response code to send
 * @param text - response phrase to send
 * @param expires - expiration interval in seconds
 * @param contact - contact to add to reply
 * @returns the tmn.r_reply returned value value
 */
int S_SUBSCRIBE_reply(struct sip_msg *msg, int code,  char *text,int *expires,str *contact)
{
	str hdr={0,0};
	tmb.t_newtran(msg);
	
	if (expires){
		hdr.len = expires_hdr1.len+12+expires_hdr1.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s){
			LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n",
				hdr.len);			
		}else{
			hdr.len=0;
			STR_APPEND(hdr,expires_hdr1);
			sprintf(hdr.s+hdr.len,"%d",*expires);
			hdr.len += strlen(hdr.s+hdr.len);
			STR_APPEND(hdr,expires_hdr2);
			cscf_add_header_rpl(msg,&hdr);		
			pkg_free(hdr.s);
		}
	}

	if (contact){
		hdr.len = contact_hdr1.len+contact->len+contact_hdr2.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s){
			LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n",
				hdr.len);			
		}else{
			hdr.len=0;
			STR_APPEND(hdr,contact_hdr1);
			STR_APPEND(hdr,*contact);
			STR_APPEND(hdr,contact_hdr2);
			cscf_add_header_rpl(msg,&hdr);		
			pkg_free(hdr.s);
		}
	}
	
	return tmb.t_reply(msg,code,text);
}
示例#10
0
/**
 * This function sends a bye in the specified dialog 
 * the callback function and parameter are the specified arguments
 * @param d - the dlg_t to send it on
 * @param cb -the callback function
 * @param dir -the direction to identify this s_dialog
 * @param reason - a reason header to include - see the 
 * @returns 1 on success or 0 on failure
 */
int send_bye(dlg_t *d,transaction_cb cb,enum s_dialog_direction dir,str reason)
{
	str bye_header_s={0,0};
	str reason_header_s={0,0};
	
	if (reason.len!=0)
		reason_header_s = reason;
	 else 
		reason_header_s = default_reason_s;

	bye_header_s.len = reason_header_s.len+content_length_s.len;
	bye_header_s.s = pkg_malloc(bye_header_s.len);
	if (!bye_header_s.s) {
		LOG(L_ERR,"ERR:"M_NAME":send_bye(): error allocating %d bytes\n",bye_header_s.len);
		goto error;
	}
	bye_header_s.len=0;
	STR_APPEND(bye_header_s,reason_header_s);
	STR_APPEND(bye_header_s,content_length_s);
				
	if(d!=NULL)	{
		enum s_dialog_direction *cbp;
		cbp = shm_malloc(sizeof(enum s_dialog_direction));
		if (!cbp){
			LOG(L_ERR,"ERR:"M_NAME":send_bye(): error allocating %d bytes\n",sizeof(enum s_dialog_direction));
			goto error;
		}		
		*cbp = dir;
		dialogb.request_inside(&bye_s, &bye_header_s, 0, d,cb,cbp);
		if (bye_header_s.s) pkg_free(bye_header_s.s);	
		return 1;
	}	
error:
	if (bye_header_s.s) pkg_free(bye_header_s.s);	
	return 0;
}
示例#11
0
/**
 * \brief Store metadata information
 */
void Storage::storeMetadata(metadata* mdata)
{
	std::stringstream ss;
	
	/* Geolocation info */
	ss << "\"srcAS\": \"" << mdata->srcAS << "\", ";
	ss << "\"dstAS\": \"" << mdata->dstAS << "\", ";
	ss << "\"srcCountry\": \"" << mdata->srcCountry << "\", ";
	ss << "\"dstCountry\": \"" << mdata->dstCountry << "\", ";
	ss << "\"srcName\": \"" << mdata->srcName << "\", ";
	ss << "\"dstName\": \"" << mdata->dstName << "\", ";

	record += ss.str();

	
	/* Profiles */
	STR_APPEND(record, "\"profiles\": [");
	if (mdata->channels) {
		// Get name of root profile
		void *profile_ptr = NULL;
		void *prev_profile_ptr = NULL;
		const char *root_profile_name;

		profile_ptr = channel_get_profile(mdata->channels[0]);
		while (profile_ptr != NULL) {
			prev_profile_ptr = profile_ptr;
			profile_ptr = profile_get_parent(profile_ptr);
		}
		root_profile_name = profile_get_name(prev_profile_ptr);

		// Process all channels
		for (int i = 0; mdata->channels[i] != 0; ++i) {
			if (i > 0) {
				STR_APPEND(record, ", ");
			}

			STR_APPEND(record, "{\"profile\": \"");
			record += root_profile_name;
			STR_APPEND(record, "/");
			record += profile_get_path(channel_get_profile(mdata->channels[i]));

			STR_APPEND(record, "\", \"channel\": \"");
			record += channel_get_name(mdata->channels[i]);
			STR_APPEND(record, "\"}");
		}
	}
	record += ']';
}
示例#12
0
/**
 * \brief Read raw data from record
 */
void Storage::readRawData(uint16_t &length, uint8_t* data_record, uint16_t &offset)
{
	/* Read raw value */
	switch (length) {
	case 1:
		sprintf(buffer.data(), "%" PRIu16, static_cast<int>(read8(data_record + offset)));
		break;
	case 2:
		sprintf(buffer.data(), "%" PRIu16, ntohs(read16(data_record + offset)));
		break;
	case 4:
		sprintf(buffer.data(), "%" PRIu32, ntohl(read32(data_record + offset)));
		break;
	case 8:
		sprintf(buffer.data(), "%" PRIu64, be64toh(read64(data_record + offset)));
		break;
	default:
		length = this->realLength(length, data_record, offset);

		if (length == 0) {
			STR_APPEND(record, "null");
			return;
		}

		if (length * 2 > buffer.capacity()) {
			buffer.reserve(length * 2 + 1);
		}

		/* Start the string with 0x and print the rest in hexa */
		strncpy(buffer.data(), "0x", 3);
		for (int i = 0; i < length; i++) {
			sprintf(buffer.data() + i * 2 + 2, "%02x", (data_record + offset)[i]);
		}
	}

	record += '"';
	record += buffer.data();
	record += '"';
}
static gchar *
_memory_properties_to_string (VkMemoryPropertyFlags prop_bits)
{
  GString *s;
  gboolean first = TRUE;

#define STR_APPEND(s,str) \
  G_STMT_START { \
    if (!first) \
      g_string_append (s, "|"); \
    g_string_append (s, str); \
    first = FALSE; \
  } G_STMT_END

  s = g_string_new (NULL);
  if (prop_bits & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
    STR_APPEND (s, "device-local");
  }
  if (prop_bits & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
    STR_APPEND (s, "host-visible");
    if (prop_bits & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
      STR_APPEND (s, "host-coherent");
    } else {
      STR_APPEND (s, "host-incoherent");
    }
    if (prop_bits & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
      STR_APPEND (s, "host-cached");
    } else {
      STR_APPEND (s, "host-uncached");
    }
  }

  if (prop_bits & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
    STR_APPEND (s, "lazily-allocated");
  }

  return g_string_free (s, FALSE);
}
示例#14
0
/**
 * Creates the full reginfo XML.
 * @param pv - the r_public to create for
 * @param event_type - event type
 * @param subsExpires - subscription expiration
 * @returns the str with the XML content
 */
str r_get_reginfo_full(void *pv,int event_type,long *subsExpires)
{		
	str x={0,0};
	str buf,pad;	
	char bufc[MAX_REGINFO_SIZE],padc[MAX_REGINFO_SIZE];

	r_public *p=(r_public*)pv,*p2;
	r_contact *c;
	r_contact_param *cp;
	ims_public_identity *pi;
	int i,j;
	unsigned int hash;
	
	buf.s = bufc;
	buf.len=0;
	pad.s = padc;
	pad.len=0;
	
	*subsExpires = r_update_subscription_status(p);
	
	STR_APPEND(buf,xml_start);
	sprintf(pad.s,r_reginfo_s.s,"%d",r_full.len,r_full.s);
	pad.len = strlen(pad.s);
	STR_APPEND(buf,pad);
	
	
	if (p->s){
		for(i=0;i<p->s->service_profiles_cnt;i++)
			for(j=0;j<p->s->service_profiles[i].public_identities_cnt;j++){
				pi = &(p->s->service_profiles[i].public_identities[j]);
				if (!pi->barring){
					hash = get_aor_hash(pi->public_identity,r_hash_size);
					if (hash == p->hash) /* because we already have the lock on p->hash */
						p2 = get_r_public_nolock(pi->public_identity);
					else 
						p2 = get_r_public(pi->public_identity);
					if (p2){
						if (p2->reg_state==REGISTERED)
							sprintf(pad.s,registration_s.s,p2->aor.len,p2->aor.s,p2,r_active.len,r_active.s);
						else 
							sprintf(pad.s,registration_s.s,p2->aor.len,p2->aor.s,p2,r_terminated.len,r_terminated.s);
						pad.len = strlen(pad.s);
						STR_APPEND(buf,pad);
						c = p2->head;
						while(c){
							if(c->qvalue != -1) {
								float q = (float)c->qvalue/1000;
								sprintf(pad.s,contact_s_q.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now, q);
							}
							else
								sprintf(pad.s,contact_s.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now);
							pad.len = strlen(pad.s);
							STR_APPEND(buf,pad);							
							STR_APPEND(buf,uri_s);
							STR_APPEND(buf,c->uri);
							STR_APPEND(buf,uri_e);
							for(cp=c->parameters;cp;cp=cp->next){
								sprintf(pad.s,unknown_param_s.s,cp->name.len,cp->name.s);
								pad.len = strlen(pad.s);
								STR_APPEND(buf,pad);
								STR_APPEND(buf,cp->value);
								STR_APPEND(buf,unknown_param_e);
							}
							STR_APPEND(buf,contact_e);
							c = c->next;
						}
						STR_APPEND(buf,registration_e);
						if (p2->hash != p->hash) r_unlock(p2->hash);
					}
				}
			}				
	}

	STR_APPEND(buf,r_reginfo_e);

	
	x.s = pkg_malloc(buf.len+1);
	if (x.s){
		x.len = buf.len;
		memcpy(x.s,buf.s,buf.len);
		x.s[x.len]=0;
	}
	return x;
}
示例#15
0
/**
 * Function that releases a call in early or early200 situation
 * early200 is when the callee has already sent out 200 but that hasn't
 * arrived yet to the caller
 * @param d - p_dialog of the call
 * @situation - flag to distinguish between two situations
 * @return 0 on error 1 on success
 * 
 * \note This function shouldn't be called directly!
 * use release_call_early or release_call_early200 instead 
 * 
 * \note This function is full of tricks to fake states and
 * to decieve the transaction module so that it lets us
 * end a call in weird state
 * 
 * \note any move in the order of functions to clarify the structure
 * can lead to a crash in P-CSCF so watch out!
 */
int release_call_previous(p_dialog *d,enum release_call_situation situation,int reason_code,str reason_text)
{
	struct cell* t;
	p_dialog *o;
	enum p_dialog_direction odir;
	int i;
	str r;
	str hdrs={0,0};	
	char buf[256];
	
	LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Releasing call <%.*s> DIR[%d].\n",
		d->call_id.len,d->call_id.s,d->direction);
	
	r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s",
		reason_hdr_s.len,reason_hdr_s.s,
		reason_code,
		reason_hdr_1.len,reason_hdr_1.s,
		reason_text.len,reason_text.s,
		reason_hdr_e.len,reason_hdr_e.s);
	r.s = buf;

	hdrs.len = r.len+content_length_s.len;	
	hdrs.s = pkg_malloc(hdrs.len);
	if (!hdrs.s){
		LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Error allocating %d bytes.\n",hdrs.len);
		hdrs.len=0;
		goto error;
	}
	hdrs.len=0;
	STR_APPEND(hdrs,r);
	STR_APPEND(hdrs,content_length_s);	
													
	/* get the dialog in the other direction to see if something going on there and mark as in releasing */
	switch (d->direction){
		case DLG_MOBILE_ORIGINATING:
			odir = DLG_MOBILE_TERMINATING;
			break;
		case DLG_MOBILE_TERMINATING:
			odir = DLG_MOBILE_ORIGINATING;
			break;
		default:
			odir = d->direction;
	}	
	
	o = get_p_dialog_dir_nolock(d->call_id,odir);
	if (o && !o->is_releasing) o->is_releasing = 1;
		
	d->is_releasing++;
		
	if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){
		LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction);
		del_p_dialog(d);
		goto error;
	}
	
	alter_dialog_route_set(d->dialog_c,d->direction);
	
	d->state=DLG_STATE_TERMINATED_ONE_SIDE;
	/*this is just a trick to use the same callback function*/	
	
	/*trick or treat!*/
	d->dialog_c->state=DLG_CONFIRMED;
	
	if (situation == RELEASE_CALL_WEIRD){
		send_request(method_ACK_s,hdrs,d->dialog_c,0,0);
		send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction);
		//d->dialog_c->state=DLG_EARLY;
	} else {/*(situation == RELEASE_CALL_EARLY)*/		
		send_request(method_CANCEL_s,hdrs,d->dialog_c,confirmed_response,d->direction);
		//d->dialog_c->state=DLG_EARLY;
	}

	/*i need the cell of the invite!!*/
	/*this is very experimental
	 * and very tricky too*/
	t=tmb.t_gett();
	
	if (t && t->uas.request) {
		/*first trick: i really want to get this reply sent even though we are onreply*/
		*tmb.route_mode=MODE_ONFAILURE;
		
		/*second trick .. i haven't recieve any response from the uac
		 * if i don't do this i get a cancel sent to the S-CSCF .. its not a big deal*/
		 /*if i cared about sip forking then probably i would not do that and let the 
		  * CANCEL go to the S-CSCF (reread specifications needed)*/
		for (i=0; i< t->nr_of_outgoings; i++)
			t->uac[i].last_received=99;
		/*t->uas.status=100;*/ /*no one cares about this*/
		/*now its safe to do this*/
		
		tmb.t_reply(t->uas.request,reason_code,reason_text.s);
		*tmb.route_mode=MODE_ONREPLY;
		tmb.t_release(t->uas.request);

		/*needed because if not i get last message retransmited... 
		 * probably there is a more logical way to do this.. but since i really
		 * want this transaction to end .. whats the point?*/
	}
	
	return 1;
error:
	if (hdrs.s) pkg_free(hdrs.s);
	return 0;	
}
示例#16
0
文件: security.c 项目: asyn/openvims
/**
 * Process the 401 response for REGISTER and creates the first Security-Associations.
 * IPSEc: Only the SA for P_Inc_Req - Incoming Requests is set now as the next REGISTER
 * could come over that one. 
 * @param rpl - the 401 response
 * @param str1 - not used
 * @param str2 - not used
 * @returns 1 if ok, 0 if not
 */
int P_security_401(struct sip_msg *rpl,char *str1, char *str2)
{
	struct sip_msg *req;
	struct hdr_field *hdr;	
	str sec_hdr,sec_srv={0,0};
	r_security_type sec_type;
	char cmd[256];
	r_contact *c;
	r_ipsec *ipsec;
	float sec_q=-1;
	str auth;

	if (!pcscf_use_ipsec &&!pcscf_use_tls) goto	ret_false;
	
	req = cscf_get_request_from_reply(rpl);
	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_security_401: No transactional request found.\n");
		goto error;
	}
	auth = cscf_get_authenticate(rpl,&hdr);
	if (!auth.len){
		LOG(L_ERR,"ERR:"M_NAME":P_security_401: No WWW-Authenticate header found.\n");
		goto ret_false; 
	}
	
	sec_hdr = cscf_get_pref_security_header(req,s_security_client, &sec_type,&sec_q);
	if (!sec_hdr.len) {	
		LOG(L_DBG,"DBG:"M_NAME":P_security_401: No Security-Client header found.\n");
		goto ret_false;
	}
	LOG(L_INFO,"DBG:"M_NAME":P_security_401: Security-Client header found : <%.*s>.\n", sec_hdr.len, sec_hdr.s);	


	/* save data into registrar */
	c = save_contact_security(req, auth, sec_hdr, sec_type, sec_q);	
	if (!c) goto error;
	switch(sec_type){
		case SEC_NONE:
			break;
		case SEC_TLS:			
			/* try to add the Security-Server header */		
			sec_srv.len = s_security_server_s.len+sec_hdr.len+s_security_server_e.len;
			sec_srv.s = pkg_malloc(sec_srv.len);
			if (!sec_srv.s){
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len);
				goto error;
			}
			sec_srv.len=0;
			STR_APPEND(sec_srv,s_security_server_s);
			STR_APPEND(sec_srv,sec_hdr);
			STR_APPEND(sec_srv,s_security_server_e);

			if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) {
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s);
				pkg_free(sec_srv.s);
				goto error;
			}
			break;
		case SEC_IPSEC:
			ipsec = c->security_temp->data.ipsec;
			/* try to add the Security-Server header */
			sprintf(cmd,"Security-Server: ipsec-3gpp; ealg=%.*s; alg=%.*s; spi-c=%d; spi-s=%d; port-c=%d; port-s=%d; q=0.1\r\n",
				ipsec->r_ealg.len,ipsec->r_ealg.s,
				ipsec->r_alg.len,ipsec->r_alg.s,
				ipsec->spi_pc,ipsec->spi_ps,
				pcscf_ipsec_port_c,pcscf_ipsec_port_s);
			
			sec_srv.len = strlen(cmd);
			sec_srv.s = pkg_malloc(sec_srv.len);
			if (!sec_srv.s){
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len);
				goto error;
			}
			memcpy(sec_srv.s,cmd,sec_srv.len);
			if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) {
				LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s);
				pkg_free(sec_srv.s);
				goto error;
			}
	
			/* run the IPSec script */	
			/* P_Inc_Req */
			sprintf(cmd,"%s %.*s %d %s %d %d %.*s %.*s %.*s %.*s",
				pcscf_ipsec_P_Inc_Req,
				c->host.len,c->host.s,
				ipsec->port_uc,
				pcscf_ipsec_host,
				pcscf_ipsec_port_s,
				ipsec->spi_ps,
				ipsec->ealg.len,ipsec->ealg.s,
				ipsec->ck.len,ipsec->ck.s,
				ipsec->alg.len,ipsec->alg.s,
				ipsec->ik.len,ipsec->ik.s);

			r_unlock(c->hash);
				
			execute_cmd(cmd);
			break;						
	}
	
	return CSCF_RETURN_TRUE;
ret_false:
	return CSCF_RETURN_FALSE;
error:
	return CSCF_RETURN_ERROR;
}
示例#17
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn)
{
	gnutls_buffer_st out_str;
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	uint8_t value[MAX_STRING_LEN];
	gnutls_datum_t td = { NULL, 0 }, tvd = {
	NULL, 0};
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	int len;

	_gnutls_buffer_init(&out_str);

	k1 = 0;
	do {
		k1++;
		/* create a string like "tbsCertList.issuer.rdnSequence.?1"
		 */
		if (asn1_rdn_name[0] != 0)
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
				 asn1_rdn_name, k1);
		else
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
				 k1);

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

		if (result == ASN1_ELEMENT_NOT_FOUND) {
			if (k1 == 1) {
				gnutls_assert();
				result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
				goto cleanup;
			}
			break;
		}

		if (result != ASN1_VALUE_NOT_FOUND) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		k2 = 0;

		do {		/* Move to the attibute type and values
				 */
			k2++;

			if (tmpbuffer1[0] != 0)
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "%s.?%u", tmpbuffer1, k2);
			else
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "?%u", k2);

			/* Try to read the RelativeDistinguishedName attributes.
			 */

			len = sizeof(value) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer2, value,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			if (result != ASN1_VALUE_NOT_FOUND) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the OID 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".type");

			len = sizeof(oid) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer3, oid,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			else if (result != ASN1_SUCCESS) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the Value 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".value");

			len = 0;

			result =
			    _gnutls_x509_read_value(asn1_struct,
						    tmpbuffer3, &tvd);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
			/*   The encodings of adjoining RelativeDistinguishedNames are separated
			 *   by a comma character (',' ASCII 44).
			 */

			/*   Where there is a multi-valued RDN, the outputs from adjoining
			 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
			 *   character.
			 */
			if (k1 != 1) {	/* the first time do not append a comma */
				if (k2 != 1) {	/* adjoining multi-value RDN */
					STR_APPEND("+");
				} else {
					STR_APPEND(",");
				}
			}

			ldap_desc =
			    gnutls_x509_dn_oid_name(oid,
						    GNUTLS_X509_DN_OID_RETURN_OID);

			STR_APPEND(ldap_desc);
			STR_APPEND("=");

			result =
			    _gnutls_x509_dn_to_string(oid, tvd.data,
						      tvd.size, &td);
			if (result < 0) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Cannot parse OID: '%s' with value '%s'\n",
				     oid, _gnutls_bin2hex(tvd.data,
							  tvd.size,
							  tmpbuffer3,
							  sizeof
							  (tmpbuffer3),
							  NULL));
				goto cleanup;
			}

			DATA_APPEND(td.data, td.size);
			_gnutls_free_datum(&td);
			_gnutls_free_datum(&tvd);
		}
		while (1);
	}
	while (1);

	result = _gnutls_buffer_to_datum(&out_str, dn, 1);
	if (result < 0)
		gnutls_assert();

	goto cleanup1;

      cleanup:
	_gnutls_buffer_clear(&out_str);
      cleanup1:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;

}
示例#18
0
int I_scscf_select(struct sip_msg* msg, char* str1, char* str2)
{
	str call_id,scscf_name={0,0};
	struct sip_msg *req;
	int result;
	str hdr={0,0};

	//print_scscf_list(L_ERR);
		
	call_id = cscf_get_call_id(msg,0);
	LOG(L_DBG,"DBG:"M_NAME":I_scscf_select(): <%.*s>\n",call_id.len,call_id.s);
	if (!call_id.len)
		return CSCF_RETURN_FALSE;
	
	scscf_name = take_scscf_entry(call_id);
	if (!scscf_name.len){
		I_scscf_drop(msg,str1,str2);
		cscf_reply_transactional(msg,600,MSG_600_FORWARDING_FAILED);			
		return CSCF_RETURN_BREAK;
	}
	
	if (msg->first_line.u.request.method.len==8 &&
		strncasecmp(msg->first_line.u.request.method.s,"REGISTER",8)==0) {
		/* REGISTER fwding */			
		if (str1&&str1[0]=='0'){
			/* first time */	
			//LOG(L_CRIT,"rewrite uri\n");
			if (rewrite_uri(msg, &(scscf_name)) < 0) {
				LOG(L_ERR,"ERR:"M_NAME":I_UAR_forward: Unable to Rewrite URI\n");
				result = CSCF_RETURN_FALSE;
			}else
				result = CSCF_RETURN_TRUE;
		}else{
			/* subsequent */
			//LOG(L_CRIT,"append branch\n");
			req = msg;//cscf_get_request_from_reply(msg);
			append_branch(req,scscf_name.s,scscf_name.len,0,0,0,0);
			result = CSCF_RETURN_TRUE;
		}
	}else{
		/* Another request */
		result = CSCF_RETURN_TRUE;
		
		hdr.len = route_hdr_s.len+scscf_name.len+route_hdr_e.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s){
			LOG(L_ERR,"ERR:"M_NAME":Mw_REQUEST_forward: Error allocating %d bytes\n",
				hdr.len);
			result = CSCF_RETURN_TRUE;
		}
		hdr.len=0;
		STR_APPEND(hdr,route_hdr_s);
		STR_APPEND(hdr,scscf_name);
		STR_APPEND(hdr,route_hdr_e);
	
		if (!cscf_add_header_first(msg,&hdr,HDR_ROUTE_T)){
			pkg_free(hdr.s);
			result = CSCF_RETURN_TRUE;
		}
		
		if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);	
		STR_PKG_DUP(msg->dst_uri,scscf_name,"pkg");
	}

	if (scscf_name.s) shm_free(scscf_name.s);
	return result;
out_of_memory:	
	if (scscf_name.s) shm_free(scscf_name.s);
	return CSCF_RETURN_ERROR;
}
示例#19
0
/**
 * Force Service routes (upon request)
 */
int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
	struct hdr_field *it;
	int i;
	str new_route_header;
	struct lump* lmp = NULL;
	char * buf;
	pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED,0 ,0);
//	char srcip[20];
//	str received_host;
        struct via_body* vb;
        unsigned short port;
        unsigned short proto;
	
	// Contact not found => not following service-routes
	if (c == NULL) return -1;

	/* we need to be sure we have seen all HFs */
	parse_headers(_m, HDR_EOH_F, 0);

        vb = cscf_get_ue_via(_m);
        port = vb->port?vb->port:5060;
        proto = vb->proto;
        
	/* Save current buffer */
	buf = _m->buf;

	// Delete old Route headers:
	if (_m->route) {
		for (it = _m->route; it; it = it->next) {
			if (it->type == HDR_ROUTE_T) {
				if ((lmp = del_lump(_m, it->name.s - buf, it->len, HDR_ROUTE_T)) == 0) {
					LM_ERR("del_lump failed \n");
					return -1;
				}
			}
		}
	}

	/* Reset dst_uri if previously set either by loose route or manually */
	if (_m->dst_uri.s && _m->dst_uri.len) {
		pkg_free(_m->dst_uri.s);
		_m->dst_uri.s = NULL;
		_m->dst_uri.len = 0;
	}
	
//	received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
//	received_host.s = srcip;

	/* Lock this record while working with the data: */
	ul.lock_udomain(_d, &vb->host, port, proto);

	if (c->num_service_routes > 0) {
		/* Create anchor for new Route-Header: */
		lmp = anchor_lump(_m, _m->headers->name.s - buf,0,0);
		if (lmp == 0) {
			LM_ERR("Failed to get anchor lump\n");
			goto error;
		}	
		/* Calculate the length: */
		new_route_header.len = route_start.len +
			route_end.len + (c->num_service_routes-1) * route_sep.len;

		for(i=0; i< c->num_service_routes; i++)
			new_route_header.len+=c->service_routes[i].len;		
		/* Allocate the memory for this new header: */
		new_route_header.s = pkg_malloc(new_route_header.len);
		if (!new_route_header.s) {
			LM_ERR("Error allocating %d bytes\n", new_route_header.len);
			goto error;
		}
		
		/* Construct new header */
		new_route_header.len = 0;
		STR_APPEND(new_route_header, route_start);
		for(i=0; i < c->num_service_routes; i++) {
			if (i) STR_APPEND(new_route_header, route_sep);
			STR_APPEND(new_route_header, c->service_routes[i]);
		}
		STR_APPEND(new_route_header, route_end);

		LM_DBG("Setting route header to <%.*s> \n", new_route_header.len, new_route_header.s);

		if ((lmp = insert_new_lump_after(lmp, new_route_header.s, new_route_header.len, HDR_ROUTE_T)) == 0) {
			LM_ERR("Error inserting new route set\n");
			pkg_free(new_route_header.s);
			goto error;
		}

		LM_DBG("Setting dst_uri to <%.*s> \n", c->service_routes[0].len,
			c->service_routes[0].s);

		if (set_dst_uri(_m, &c->service_routes[0]) !=0 ) {
			LM_ERR("Error setting new dst uri\n");
			goto error;
		}
	}
	/* Unlock domain */
	ul.unlock_udomain(_d, &vb->host, port, proto);
	return 1;
error:
	/* Unlock domain */
	ul.unlock_udomain(_d, &vb->host, port, proto);
	return -1;
	
    return 1;
}
示例#20
0
static int stateobj_spy(struct state_object * self, int x, int input, int z, int t)
{
    int old_state = self->current_state;
    int ans = StateTransition(self, x, input, z, t);
    int new_state = self->current_state;
    
    if (self == SBS_STATE) { STR_APPEND(log, "SBS  :"); }
    else if (self == SCS_STATE) { STR_APPEND(log, "SCS  :"); }
    else if (self == SCSES_STATE) { STR_APPEND(log, "SCSes:"); }
    else if (self == SCSSR_STATE) { STR_APPEND(log, "SCSsr:"); }
    else if (self == SDS_REAR_STATE) { STR_APPEND(log, "SDSr :"); }
    else if (self == SDS_FRONT1_STATE) { STR_APPEND(log, "SDSf1:"); }
    else if (self == SDS_FRONT2_STATE) { STR_APPEND(log, "SDSf2:"); }
    else if (self == SDS_FRONT3_STATE) { STR_APPEND(log, "SDSf3:"); }
    else if (self == SDS_FRONT4_STATE) { STR_APPEND(log, "SDSf4:"); }
    else if (self == SPS_STATE) { STR_APPEND(log, "SPS  :"); }
    else if (self == FSS_STATE) { STR_APPEND(log, "FSS  :"); }
    else if (self == FCS_STATE) { STR_APPEND(log, "FCS  :"); }
    
    STR_APPEND(log, "(%d) -- %2d -->(%d)\n", old_state, input, new_state);
    
    return ans;
}
示例#21
0
static int append_elements(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_buffer_st *str, int k1, unsigned last)
{
	int k2, result, max_k2;
	int len;
	uint8_t value[MAX_STRING_LEN];
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	gnutls_datum_t td = { NULL, 0 };
	gnutls_datum_t tvd = { NULL, 0 };

	/* create a string like "tbsCertList.issuer.rdnSequence.?1"
	 */
	if (asn1_rdn_name[0] != 0)
		snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
			 asn1_rdn_name, k1);
	else
		snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
			 k1);

	len = sizeof(value) - 1;
	result =
	    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

	if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	k2 = 0;

	result = asn1_number_of_elements(asn1_struct, tmpbuffer1, &max_k2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	do {		/* Move to the attibute type and values
				 */
		k2++;

		if (tmpbuffer1[0] != 0)
			snprintf(tmpbuffer2, sizeof(tmpbuffer2),
				 "%s.?%u", tmpbuffer1, k2);
		else
			snprintf(tmpbuffer2, sizeof(tmpbuffer2),
				 "?%u", k2);

		/* Try to read the RelativeDistinguishedName attributes.
		 */

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer2, value,
				    &len);

		if (result == ASN1_ELEMENT_NOT_FOUND)
			break;
		if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		/* Read the OID 
		 */
		_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
				tmpbuffer2);
		_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
				".type");

		len = sizeof(oid) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer3, oid,
				    &len);

		if (result == ASN1_ELEMENT_NOT_FOUND)
			break;
		else if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		/* Read the Value 
		 */
		_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
				tmpbuffer2);
		_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
				".value");

		len = 0;

		result =
		    _gnutls_x509_read_value(asn1_struct,
					    tmpbuffer3, &tvd);
		if (result < 0) {
			gnutls_assert();
			goto cleanup;
		}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
		/*   The encodings of adjoining RelativeDistinguishedNames are separated
		 *   by a comma character (',' ASCII 44).
		 */

		ldap_desc =
		    gnutls_x509_dn_oid_name(oid,
					    GNUTLS_X509_DN_OID_RETURN_OID);

		STR_APPEND(ldap_desc);
		STR_APPEND("=");

		result =
		    _gnutls_x509_dn_to_string(oid, tvd.data,
					      tvd.size, &td);
		if (result < 0) {
			gnutls_assert();
			_gnutls_debug_log
			    ("Cannot parse OID: '%s' with value '%s'\n",
			     oid, _gnutls_bin2hex(tvd.data,
						  tvd.size,
						  tmpbuffer3,
						  sizeof
						  (tmpbuffer3),
						  NULL));
			goto cleanup;
		}

		DATA_APPEND(td.data, td.size);
		_gnutls_free_datum(&td);
		_gnutls_free_datum(&tvd);

		/*   Where there is a multi-valued RDN, the outputs from adjoining
		 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
		 *   character.
		 */
		if (k2 < max_k2) {
			STR_APPEND("+");
		} else if (!last) {
			STR_APPEND(",");
		}
	}
	while (1);

	result = 0;

 cleanup:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;
}
示例#22
0
/**
 * \brief Store data record
 */
void Storage::storeDataRecord(struct metadata *mdata, struct json_conf * config)
{
	const char *element_name = NULL;
	ELEMENT_TYPE element_type;

	offset = 0;
	uint16_t trans_len = 0;
	const char *trans_str = NULL;
	record.clear();
	STR_APPEND(record, "{\"@type\": \"ipfix.entry\", ");

	struct ipfix_template *templ = mdata->record.templ;
	uint8_t *data_record = (uint8_t*) mdata->record.record;

	/* get all fields */
	uint16_t added = 0;
	for (uint16_t count = 0, index = 0; count < templ->field_count; ++count, ++index) {
		/* Get Enterprise number and ID */
		id = templ->fields[index].ie.id;
		length = templ->fields[index].ie.length;
		enterprise = 0;
		
		if (id & 0x8000) {
			id &= 0x7fff;
			enterprise = templ->fields[++index].enterprise_number;
		}
		
		/* Get element informations */
		const ipfix_element_t * element = get_element_by_id(id, enterprise);
		if (element != NULL) {
			element_name = element->name;
			element_type = element->type;
		} else {
			// Element not found
			if (config->ignoreUnknown) {
				offset += realLength(length, data_record, offset);
				continue;
			}

			element_name = rawName(enterprise, id);
			element_type = ET_UNASSIGNED;
			MSG_DEBUG(msg_module, "Unknown element (%s)", element_name);
	}

		if (added > 0) {
			STR_APPEND(record, ", ");
		}

		STR_APPEND(record, "\"");
		record += config->prefix;
		record += element_name;
		STR_APPEND(record, "\": ");

		switch (element_type) {
		case ET_UNSIGNED_8:
		case ET_UNSIGNED_16:
		case ET_UNSIGNED_32:
		case ET_UNSIGNED_64:{
			trans_str = translator.toUnsigned(length, &trans_len, data_record, offset,
				element, config);
			record.append(trans_str, trans_len);
		}
			break;
		case ET_SIGNED_8:
		case ET_SIGNED_16:
		case ET_SIGNED_32:
		case ET_SIGNED_64:
			trans_str = translator.toSigned(length, &trans_len, data_record, offset);
			record.append(trans_str, trans_len);
			break;
		case ET_FLOAT_32:
		case ET_FLOAT_64:
			trans_str = translator.toFloat(length, &trans_len, data_record, offset);
			record.append(trans_str, trans_len);
			break;
		case ET_IPV4_ADDRESS:
			record += '"';
			trans_str = translator.formatIPv4(read32(data_record + offset), &trans_len);
			record.append(trans_str, trans_len);
			record += '"';
			break;
		case ET_IPV6_ADDRESS:
			READ_BYTE_ARR(addr6, data_record + offset, IPV6_LEN);
			record += '"';
			record += translator.formatIPv6(addr6);
			record += '"';
			break;
		case ET_MAC_ADDRESS:
			READ_BYTE_ARR(addrMac, data_record + offset, MAC_LEN);
			record += '"';
			record += translator.formatMac(addrMac);
			record += '"';
			break;
		case ET_DATE_TIME_SECONDS:
			record += translator.formatTimestamp(read32(data_record + offset),
				t_units::SEC, config);
			break;
		case ET_DATE_TIME_MILLISECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::MILLISEC, config);
			break;
		case ET_DATE_TIME_MICROSECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::MICROSEC, config);
			break;
		case ET_DATE_TIME_NANOSECONDS:
			record += translator.formatTimestamp(read64(data_record + offset),
				t_units::NANOSEC, config);
			break;
		case ET_STRING:
			length = realLength(length, data_record, offset);
			record += translator.escapeString(length, data_record + offset,
				config);
			break;
		case ET_BOOLEAN:
		case ET_UNASSIGNED: 
		default:
			readRawData(length, data_record, offset);
			break;
		}

		offset += length;
		added++;
	}
	
	/* Store metadata */
	if (processMetadata) {
		STR_APPEND(record, ", \"ipfix.metadata\": {");
		storeMetadata(mdata);
		STR_APPEND(record, "}");
	}
	
	STR_APPEND(record, "}\n");
	sendData();
}
示例#23
0
/**
 * Creates the partial reginfo XML.
 * @param pv - the r_public to create for
 * @param pc - the r_contatct to create for
 * @param event_type - event type
 * @param subsExpires - subscription expiration
 * @returns the str with the XML content
 */
str r_get_reginfo_partial( void *pv,void *pc,int event_type,long *subsExpires)
{		
	str x={0,0};
	str buf,pad;	
	char bufc[MAX_REGINFO_SIZE],padc[MAX_REGINFO_SIZE];
	int expires=-1;

	r_public *p=(r_public*)pv;
	r_contact *c=(r_contact*)pc;
	r_contact_param *cp;
	str state,event;
	
	buf.s = bufc;
	buf.len=0;
	pad.s = padc;
	pad.len=0;

	*subsExpires = r_update_subscription_status(p);
	
	STR_APPEND(buf,xml_start);
	sprintf(pad.s,r_reginfo_s.s,"%d",r_partial.len,r_partial.s);
	pad.len = strlen(pad.s);
	STR_APPEND(buf,pad);
	
	
	if (p){
		expires = c->expires-time_now;
		if (p->head == c && p->tail == c && 
			(event_type==IMS_REGISTRAR_CONTACT_EXPIRED ||
			 event_type==IMS_REGISTRAR_CONTACT_DEACTIVATED||
			 event_type==IMS_REGISTRAR_CONTACT_UNREGISTERED||
			 event_type==IMS_REGISTRAR_CONTACT_REJECTED)
		   )
			sprintf(pad.s,registration_s.s,p->aor.len,p->aor.s,p,r_terminated.len,r_terminated.s);
		else 
			sprintf(pad.s,registration_s.s,p->aor.len,p->aor.s,p,r_active.len,r_active.s);
		pad.len = strlen(pad.s);
		STR_APPEND(buf,pad);
		if (c){
			switch(event_type){
				case IMS_REGISTRAR_CONTACT_REGISTERED:
					state = r_active;
					event = r_registered;
					break;
				case IMS_REGISTRAR_CONTACT_CREATED:
					state = r_active;
					event = r_created;
					break;
				case IMS_REGISTRAR_CONTACT_REFRESHED:
					state = r_active;
					event = r_refreshed;
					break;
				case IMS_REGISTRAR_CONTACT_SHORTENED:
					state = r_active;
					event = r_shortened;
					break;
				case IMS_REGISTRAR_CONTACT_EXPIRED:
					state = r_terminated;
					event = r_expired;
					expires = 0;
					break;
				case IMS_REGISTRAR_CONTACT_DEACTIVATED:
					state = r_terminated;
					event = r_deactivated;
					break;
				case IMS_REGISTRAR_CONTACT_PROBATION:
					state = r_terminated;
					event = r_probation;
					break;
				case IMS_REGISTRAR_CONTACT_UNREGISTERED:
					state = r_terminated;
					event = r_unregistered;
					expires = 0;
					break;
				case IMS_REGISTRAR_CONTACT_REJECTED:			
					state = r_terminated;
					event = r_rejected;
					break;				
				default:
					state = r_active;
					event = r_registered;
			}
			if(c->qvalue != -1) {
                        	float q = (float)c->qvalue/1000;
                                sprintf(pad.s,contact_s_q.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now, q);
                        }
			else
				sprintf(pad.s,contact_s.s,c,state.len,state.s,event.len,event.s,expires);
			pad.len = strlen(pad.s);
			STR_APPEND(buf,pad);							
			STR_APPEND(buf,uri_s);
			STR_APPEND(buf,c->uri);
			STR_APPEND(buf,uri_e);
			for(cp=c->parameters;cp;cp=cp->next){
				sprintf(pad.s,unknown_param_s.s,cp->name.len,cp->name.s);
				pad.len = strlen(pad.s);
				STR_APPEND(buf,pad);
				STR_APPEND(buf,cp->value);
				STR_APPEND(buf,unknown_param_e);
			}			
			STR_APPEND(buf,contact_e);
			STR_APPEND(buf,registration_e);
		}
	}

	STR_APPEND(buf,r_reginfo_e);

	
	x.s = pkg_malloc(buf.len+1);
	if (x.s){
		x.len = buf.len;
		memcpy(x.s,buf.s,buf.len);
		x.s[x.len]=0;		
	}
	return x;
}
示例#24
0
static int mod_init(void) {
    registration_default_algorithm_type = get_algorithm_type(registration_default_algorithm);

#ifdef STATISTICS
	/* register statistics */
	if (register_module_stats( exports.name, mod_stats)!=0 ) {
		LM_ERR("failed to register core statistics\n");
		return -1;
	}

	if (!register_stats()){
		LM_ERR("Unable to register statistics\n");
		return -1;
	}
#endif

    /* check the max_nonce_reuse param */
    if (auth_used_vector_timeout < 0) {
        LM_WARN("bad value for auth_used_vector_timeout parameter (=%d), must be positive. Fixed to 3600\n", auth_used_vector_timeout);
        auth_used_vector_timeout = 3600;
    }

    /* check the max_nonce_reuse param */
    if (max_nonce_reuse < 0) {
        LM_WARN("bad value for max_nonce_reuse parameter (=%d), must be positive. Fixed to 0\n", max_nonce_reuse);
        max_nonce_reuse = 0;
    }

    /* load the CDP API */
    if (load_cdp_api(&cdpb) != 0) {
        LM_ERR("can't load CDP API\n");
        return -1;
    }

    /* load the TM API */
    if (load_tm_api(&tmb) != 0) {
        LM_ERR("can't load TM API\n");
        return -1;
    }

    /* Init the authorization data storage */
    if (!auth_data_init(auth_data_hash_size)) {
        LM_ERR("Unable to init auth data\n");
        return -1;
    }

    /* set default qop */
    if (registration_qop.s && registration_qop.len > 0) {
        registration_qop_str.len = s_qop_s.len + registration_qop.len
                + s_qop_e.len;
        registration_qop_str.s = pkg_malloc(registration_qop_str.len);
        if (!registration_qop_str.s) {
            LM_ERR("Error allocating %d bytes\n", registration_qop_str.len);
            registration_qop_str.len = 0;
            return 0;
        }
        registration_qop_str.len = 0;
        STR_APPEND(registration_qop_str, s_qop_s);
        memcpy(registration_qop_str.s + registration_qop_str.len,
            registration_qop.s, registration_qop.len);
        registration_qop_str.len += registration_qop.len;
        STR_APPEND(registration_qop_str, s_qop_e);
    } else {
        registration_qop_str.len = 0;
        registration_qop_str.s = 0;
    }

    /* Register the auth vector timer */
    if (register_timer(reg_await_timer, auth_data, 10) < 0) {
        LM_ERR("Unable to register auth vector timer\n");
        return -1;
    }

    return 0;
}
示例#25
0
/**
 * Creates a NOTIFY message and sends it
 * @param n - the r_notification to create the NOTIFY after
 */
void send_notification(r_notification *n)
{
	str h={0,0};
	int k=0;
#ifdef SER_MOD_INTERFACE
        uac_req_t req;
#endif
        
	LOG(L_DBG,"DBG:"M_NAME":send_notification: NOTIFY about <%.*s>\n",n->uri.len,n->uri.s);
	
	//tmb.print_dlg(stdout,n->dialog);
	
	h.len = 0;
	h.len += contact_hdr1.len + n->uri.len + contact_hdr2.len ;
	if (n->subscription_state.len) h.len += subss_hdr1.len + subss_hdr2.len + n->subscription_state.len;
	h.len+=event_hdr.len;
	h.len+=maxfwds_hdr.len;
	if (n->content_type.len) h.len += ctype_hdr1.len + ctype_hdr2.len + n->content_type.len;
	h.s = pkg_malloc(h.len);
	if (!h.s){
		LOG(L_ERR,"ERR:"M_NAME":send_notification: Error allocating %d bytes\n",h.len);
		h.len = 0;
	}

	h.len = 0;
	STR_APPEND(h,contact_hdr1);
	STR_APPEND(h,n->uri);
	STR_APPEND(h,contact_hdr2);

	STR_APPEND(h,event_hdr);
	STR_APPEND(h,maxfwds_hdr);
	if (n->subscription_state.len) {
		STR_APPEND(h,subss_hdr1);
		STR_APPEND(h,n->subscription_state);
		STR_APPEND(h,subss_hdr2);
	}
	if (n->content_type.len) {
		STR_APPEND(h,ctype_hdr1);
		STR_APPEND(h,n->content_type);
		STR_APPEND(h,ctype_hdr2);
	}
	
	//LOG(L_CRIT,"DLG:%p\n",n->dialog);
	#ifdef WITH_IMS_PM
		k = n->is_scscf_dereg;
	#endif 
	if (n->content.len)	{
#ifdef SER_MOD_INTERFACE
		set_uac_req(&req,
					&method,
					&h,
					&(n->content),
					n->dialog,
					TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED,
					uac_request_cb,
					(void*)k);
		tmb.t_request_within(&req);
#else	
		tmb.t_request_within(&method, &h, &(n->content), n->dialog, uac_request_cb, (void*)k);
#endif		
	} else { 
#ifdef SER_MOD_INTERFACE
		set_uac_req(&req,
					&method,
					0,
					&(n->content),
					n->dialog,
					TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED,
					uac_request_cb,
					(void*)k);
		tmb.t_request_within(&req);
#else	
		tmb.t_request_within(&method, &h, 0, n->dialog, uac_request_cb, (void*)k);
#endif		
	}
	if (h.s) pkg_free(h.s);
	
	#ifdef WITH_IMS_PM
		if (n->is_scscf_dereg) IMS_PM_LOG11(UR_AttDeRegCscf,n->dialog->id.call_id,n->dialog->loc_seq.value);
	#endif 
}
示例#26
0
int r_send_third_party_reg(r_third_party_registration *r, int expires) {
    str h = {0, 0};
    str b = {0, 0};
    uac_req_t req;

    LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n",
	    r->req_uri.len, r->req_uri.s);

    h.len = event_hdr.len + max_fwds_hdr.len;
    h.len += expires_s.len + 12 + expires_e.len;

    h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len;

    if (r->pvni.len)
	h.len += p_visited_network_id_s.len + p_visited_network_id_e.len
	    + r->pvni.len;

    if (r->pani.len)
	h.len += p_access_network_info_s.len + p_access_network_info_e.len
	    + r->pani.len;

    if (r->cv.len)
	h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len;

    if (r->path.len)
	h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/;

    h.s = pkg_malloc(h.len);
    if (!h.s) {
	LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
	h.len = 0;
	return 0;
    }

    h.len = 0;
    STR_APPEND(h, event_hdr);

    STR_APPEND(h, max_fwds_hdr);

    STR_APPEND(h, expires_s);
    sprintf(h.s + h.len, "%d", expires);
    h.len += strlen(h.s + h.len);
    STR_APPEND(h, expires_e);

    if (r->path.len) {
	STR_APPEND(h, path_s);
	STR_APPEND(h, path_mine_s);
	STR_APPEND(h, r->from);
	STR_APPEND(h, path_mine_e);
	STR_APPEND(h, comma);
	STR_APPEND(h, r->path);
	STR_APPEND(h, path_e);
    }

    STR_APPEND(h, contact_s);
    STR_APPEND(h, isc_my_uri_sip);
    STR_APPEND(h, contact_e);

    if (r->pvni.len) {
	STR_APPEND(h, p_visited_network_id_s);
	STR_APPEND(h, r->pvni);
	STR_APPEND(h, p_visited_network_id_e);
    }

    if (r->pani.len) {
	STR_APPEND(h, p_access_network_info_s);
	STR_APPEND(h, r->pani);
	STR_APPEND(h, p_access_network_info_e);
    }

    if (r->cv.len) {
	STR_APPEND(h, p_charging_vector_s);
	STR_APPEND(h, r->cv);
	STR_APPEND(h, p_charging_vector_e);
    }
    LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
    if (r->service_info.len) {
	b.len = body_s.len + r->service_info.len + body_e.len;
	b.s = pkg_malloc(b.len);
	if (!b.s) {
	    LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
	    b.len = 0;
	    return 0;
	}

	b.len = 0;
	STR_APPEND(b, body_s);
	STR_APPEND(b, r->service_info);
	STR_APPEND(b, body_e);
    }

    set_uac_req(&req, &method, &h, &b, 0,
	    TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED,
	    r_third_party_reg_response, &(r->req_uri));
    if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) {
	LM_ERR("r_send_third_party_reg: Error sending in transaction\n");
	goto error;
    }
    if (h.s)
	pkg_free(h.s);
    return 1;

error:
    if (h.s)
	pkg_free(h.s);
    return 0;
}
示例#27
0
/**
 * Function that releases a call in early or early200 situation
 * early200 is when the callee has already sent out 200 but that hasn't
 * arrived yet to the caller
 * @param d - p_dialog of the call
 * @situation - flag to distinguish between two situations
 * @return 0 on error 1 on success
 *
 * \note This function shouldn't be called directly!
 * use release_call_early or release_call_early200 instead
 *
 * \note This function is full of tricks to fake states and
 * to decieve the transaction module so that it lets us
 * end a call in weird state
 *
 * \note any move in the order of functions to clarify the structure
 * can lead to a crash in P-CSCF so watch out!
 */
int release_call_previous(p_dialog *d,enum release_call_situation situation,int reason_code,str reason_text)
{
    struct cell* t;
    p_dialog *o;
    enum p_dialog_direction odir;
    int i;
    str r;
    str hdrs= {0,0};
    str firstcseq;
    char buf[256];

    if(!d)
        return 0;

    LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Releasing call <%.*s> DIR[%d].\n",
        d->call_id.len,d->call_id.s,d->direction);

    r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s",
                     reason_hdr_s.len,reason_hdr_s.s,
                     reason_code,
                     reason_hdr_1.len,reason_hdr_1.s,
                     reason_text.len,reason_text.s,
                     reason_hdr_e.len,reason_hdr_e.s);
    r.s = buf;

    hdrs.len = r.len+content_length_s.len;
    hdrs.s = pkg_malloc(hdrs.len);
    if (!hdrs.s) {
        LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Error allocating %d bytes.\n",hdrs.len);
        hdrs.len=0;
        goto error;
    }
    hdrs.len=0;
    STR_APPEND(hdrs,r);
    STR_APPEND(hdrs,content_length_s);

    /* get the dialog in the other direction to see if something going on there and mark as in releasing */
    switch (d->direction) {
    case DLG_MOBILE_ORIGINATING:
        odir = DLG_MOBILE_TERMINATING;
        break;
    case DLG_MOBILE_TERMINATING:
        odir = DLG_MOBILE_ORIGINATING;
        break;
    default:
        odir = d->direction;
    }

    time_t time_now=time(0);

    o = get_p_dialog_dir_nolock(d->call_id,odir);


    if (o && o->is_releasing==0)  {

        o->is_releasing = 1;
        // Addition from Alberto Diez the 2nd November 2007
        // the idea is to put the other one to expire in TIME_TO_EXPIRE
        // just in case no reply is received
        if (o->expires>time_now+TIME_TO_EXPIRE) {
            o->expires=time_now+TIME_TO_EXPIRE;
        }

    }
    d->is_releasing++;

    /*The first time i decrease the expire time for the dialog expire , so that i guarantee that
    	 * its going to be deleted from the table sometime*/


    if (d->expires>time_now+TIME_TO_EXPIRE)
    {
        d->expires=time_now+TIME_TO_EXPIRE;
    }

    if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE) {
        LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction);
        del_p_dialog(d);
        goto error;
    }

    if(alter_dialog_route_set(d->dialog_c,d->direction,situation)<0) {
        LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction);
        del_p_dialog(d);
        goto error;
    }

    d->state=DLG_STATE_TERMINATED_ONE_SIDE;
    /*this is just a trick to use the same callback function*/




    /*i need the cell of the invite!!*/
    /*this is very experimental
     * and very tricky too*/
    //t=tmb.t_gett();
    i=0;
    i=snprintf(buf,256,"%i",d->first_cseq); // i just use buf because its there..

    if (i==256) {
        LOG(L_ERR,"release_call_previous: some client used first CSeq way too big\n");
        goto error;
    }

    firstcseq.s=pkg_malloc(i+1); // the \0
    firstcseq.len=i;
    sprintf(firstcseq.s,"%i",d->first_cseq);
    LOG(L_INFO,"CALLED t_lookup_callid with %.*s, %.*s\n",d->call_id.len,d->call_id.s,firstcseq.len,firstcseq.s);
    if (tmb.t_lookup_callid(&t,d->call_id,firstcseq) < 0) {
        pkg_free(firstcseq.s);
        LOG(L_ERR,"release_call_previous: t_lookup_callid failed\n");
        goto error;
    }

    pkg_free(firstcseq.s);

    if (t && t!=(void*) -1  && t->uas.request) {


        if (t->method.len!=6 || t->method.s[0]!='I' || t->method.s[1]!='N' || t->method.s[2]!='V')
        {
            //well this is the transaction of a subsequent request within the dialog
            //and the dialog is not confirmed yet, so its a PRACK or an UPDATE
            //could also be an options, but the important thing is how am i going to get
            //the transaction of the invite, that is the one i have to cancel
            LOG(L_ERR,"this is not my transaction so where am i?\n");
        }


        /*first trick: i really want to get this reply sent even though we are onreply*/

#ifdef SER_MOD_INTERFACE
        route_type = FAILURE_ROUTE;
#else
        *tmb.route_mode=MODE_ONFAILURE;
#endif


        if (situation == RELEASE_CALL_WEIRD) {
            /*second trick .. i haven't recieve any response from the uac
            * if i don't do this i get a cancel sent to the S-CSCF .. its not a big deal*/
            /*if i cared about sip forking then probably i would not do that and let the
            * CANCEL go to the S-CSCF (reread specifications needed)*/
            //for (i=0; i< t->nr_of_outgoings; i++)
            //	t->uac[i].last_received=99;
            /*t->uas.status=100;*/ /*no one cares about this*/
            /*now its safe to do this*/

            /*trick or treat!*/
            for (i=0; i< t->nr_of_outgoings; i++)
                t->uac[i].last_received=99;
            t->uas.status=100;
            d->dialog_c->state=DLG_CONFIRMED;
            send_request(method_ACK_s,hdrs,d->dialog_c,0,0);
            send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction);
            d->dialog_c->state=DLG_EARLY;

            tmb.t_reply(t->uas.request,reason_code,reason_text.s);
            *tmb.route_mode=MODE_ONREPLY;
            t->uas.status=488;
            tmb.t_release(t->uas.request);
            /*needed because if not i get last message retransmited...
             * probably there is a more logical way to do this.. but since i really
             * want this transaction to end .. whats the point?*/
        } else {/*(situation == RELEASE_CALL_EARLY)*/
            d->dialog_c->loc_seq.value++;

            //d->dialog_c->state=DLG_CONFIRMED;
            //send_request(method_CANCEL_s,hdrs,d->dialog_c,confirmed_response,d->direction);
            //d->dialog_c->state=DLG_EARLY;

            tmb.t_reply(t->uas.request,reason_code,reason_text.s);

            /*
            for (i=0; i< t->nr_of_outgoings; i++)
            	t->uac[i].last_received=180;
            */

            // t_reply has decided to send a CANCEL already so no big deal!

            //tmb.cancel_uacs(t,0xFFFF,F_CANCEL_B_FAKE_REPLY);

            //t->uas.status=488;

            //tmb.t_release(t->uas.request);


            // I thought of deleting the dialog here.. but
            // a good SIP client will respond to the CANCEL with a 487
            //del_p_dialog(d);
        }
    }

    if (hdrs.s) pkg_free(hdrs.s);
    return 1;
error:
    if (hdrs.s) pkg_free(hdrs.s);
    return 0;
}
示例#28
0
/**
 * This functions sends BYE for a confirmed dialog
 * @param d - the p_dialog to end
 * @param reason - the Reason: header to include in the messages
 * @returns 0 on error 1 on success
 */
int release_call_confirmed(p_dialog *d, int reason_code, str reason_text)
{
	enum p_dialog_direction odir;
	p_dialog *o;
	str r;
	str hdrs={0,0};	
	char buf[256];
	
	LOG(L_INFO,"DBG:"M_NAME":release_call_confirmed(): Releasing call <%.*s> DIR[%d].\n",
		d->call_id.len,d->call_id.s,d->direction);
	
	r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s",
		reason_hdr_s.len,reason_hdr_s.s,
		reason_code,
		reason_hdr_1.len,reason_hdr_1.s,
		reason_text.len,reason_text.s,
		reason_hdr_e.len,reason_hdr_e.s);
	r.s = buf;

	hdrs.len = r.len+content_length_s.len;	
	hdrs.s = pkg_malloc(hdrs.len);
	if (!hdrs.s){
		LOG(L_INFO,"DBG:"M_NAME":release_call_confirmed(): Error allocating %d bytes.\n",hdrs.len);
		hdrs.len=0;
		goto error;
	}
	hdrs.len=0;	
	STR_APPEND(hdrs,r);
	STR_APPEND(hdrs,content_length_s);	
		
	/* get the dialog in the other direction to see if something going on there and mark as in releasing */
	switch (d->direction){
		case DLG_MOBILE_ORIGINATING:
			odir = DLG_MOBILE_TERMINATING;
			break;
		case DLG_MOBILE_TERMINATING:
			odir = DLG_MOBILE_ORIGINATING;
			break;
		default:
			odir = d->direction;
	}	
	
	o = get_p_dialog_dir_nolock(d->call_id,odir);
	if (o && !o->is_releasing) o->is_releasing = 1;
		
	d->is_releasing++;
		
	if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){
		LOG(L_ERR,"ERR:"M_NAME":release_call_confirmed(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction);
		del_p_dialog(d);
		goto error;
	}
	if (d->is_releasing==1) {	
		/*Before generating a request, we have to generate
		 * the route_set in the dlg , because the route set
		 * in the dialog is for the UAC everything which was in the 
		 * Record-Routes (including local address)*/
		alter_dialog_route_set(d->dialog_c,d->direction);		
		
		/*first generate the bye for called user*/
		/*then generate the bye for the calling user*/
		send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction);
		send_request(method_BYE_s,hdrs,d->dialog_s,confirmed_response,d->direction);
		
		/*the dialog is droped by the callback-function when receives the two replies */
	}	 

	if (hdrs.s) pkg_free(hdrs.s);
	return 1;
error:
	if (hdrs.s) pkg_free(hdrs.s);
	return 0;	
}
示例#29
0
/**
 * Send a subscription
 * @param s - the subsription to send for
 * @param duration - expires time
 * @returns true if OK, false if not, error on failure
 * \todo store the dialog and reSubscribe on the same dialog
 */
int r_send_subscribe(r_subscription *s,int duration)
{
	str h={0,0};

	LOG(L_DBG,"DBG:"M_NAME":r_send_subscribe: SUBSCRIBE to <%.*s>\n",
		s->req_uri.len,s->req_uri.s);
	
	h.len = event_hdr.len+accept_hdr.len+content_len_hdr.len+max_fwds_hdr.len;
	h.len += expires_s.len + 12 + expires_e.len;

	h.len += contact_s.len + pcscf_name_str.len + contact_e.len;
	if (pcscf_path_str.len) h.len += p_asserted_identity_s.len + 
		p_asserted_identity_e.len + pcscf_path_str.len;

	h.s = pkg_malloc(h.len);
	if (!h.s){
		LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error allocating %d bytes\n",h.len);
		h.len = 0;
		return 0;
	}

	h.len = 0;
	STR_APPEND(h,event_hdr);
	STR_APPEND(h,accept_hdr);
	STR_APPEND(h,content_len_hdr);
	STR_APPEND(h,max_fwds_hdr);

	STR_APPEND(h,expires_s);
	sprintf(h.s+h.len,"%d",duration);
	h.len += strlen(h.s+h.len);
	STR_APPEND(h,expires_e);

	STR_APPEND(h,contact_s);
	STR_APPEND(h,pcscf_name_str);
	STR_APPEND(h,contact_e);
	
	if (pcscf_path_str.len) {
		STR_APPEND(h,p_asserted_identity_s);
		STR_APPEND(h,pcscf_path_str);
		STR_APPEND(h,p_asserted_identity_e);
	}
	
	if (!s->dialog){
		/* this is the first request in the dialog */
		if (tmb.new_dlg_uac(0,0,1,&pcscf_name_str,&s->req_uri,&s->dialog)<0){
			LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error creating a dialog for SUBSCRIBE\n");
			goto error;
		}
		if (dialogb.request_outside(&method, &h, 0, s->dialog, r_subscribe_response,  &(s->req_uri)) < 0){
			LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending initial request in a SUBSCRIBE dialog\n");
			goto error;
		}		
	}else{
		/* this is a subsequent subscribe */
		if (dialogb.request_inside(&method, &h, 0, s->dialog, r_subscribe_response,  &(s->req_uri)) < 0){
			LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending subsequent request in a SUBSCRIBE dialog\n");
			goto error;
		}				
	}

	if (h.s) pkg_free(h.s);
	return 1;

error:
	if (h.s) pkg_free(h.s);
	return 0;
}
示例#30
0
文件: dn.c 项目: uvbs/SupportCenter
/* Parses an X509 DN in the asn1_struct, and puts the output into
 * the string buf. The output is an LDAP encoded DN.
 *
 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
 * That is to point in the rndSequence.
 */
int
_gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
		       const char *asn1_rdn_name, char *buf,
		       size_t * sizeof_buf)
{
  gnutls_string out_str;
  int k2, k1, result;
  char tmpbuffer1[MAX_NAME_SIZE];
  char tmpbuffer2[MAX_NAME_SIZE];
  char tmpbuffer3[MAX_NAME_SIZE];
  opaque value[MAX_STRING_LEN], *value2 = NULL;
  char *escaped = NULL;
  const char *ldap_desc;
  char oid[128];
  int len, printable;
  char *string = NULL;
  size_t sizeof_string, sizeof_escaped;

  if (sizeof_buf == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (buf)
    buf[0] = 0;
  else
    *sizeof_buf = 0;

  _gnutls_string_init (&out_str, gnutls_malloc, gnutls_realloc, gnutls_free);

  k1 = 0;
  do
    {

      k1++;
      /* create a string like "tbsCertList.issuer.rdnSequence.?1"
       */
      if (asn1_rdn_name[0]!=0)
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name, k1);
      else
        snprintf( tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
      
      len = sizeof (value) - 1;
      result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);

      if (result == ASN1_ELEMENT_NOT_FOUND)
	{
	  break;
	}

      if (result != ASN1_VALUE_NOT_FOUND)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      k2 = 0;

      do
	{			/* Move to the attibute type and values
				 */
	  k2++;

          if (tmpbuffer1[0] != 0)
  	    snprintf( tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1, k2);
          else
  	    snprintf( tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);

	  /* Try to read the RelativeDistinguishedName attributes.
	   */

	  len = sizeof (value) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    break;
	  if (result != ASN1_VALUE_NOT_FOUND)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  /* Read the OID 
	   */
	  _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	  _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");

	  len = sizeof (oid) - 1;
	  result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);

	  if (result == ASN1_ELEMENT_NOT_FOUND)
	    break;
	  else if (result != ASN1_SUCCESS)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }

	  /* Read the Value 
	   */
	  _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
	  _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");

	  len = 0;
	  result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len);

	  value2 = gnutls_malloc (len);
	  if (value2 == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);

	  if (result != ASN1_SUCCESS)
	    {
	      gnutls_assert ();
	      result = _gnutls_asn2err (result);
	      goto cleanup;
	    }
#define STR_APPEND(y) if ((result=_gnutls_string_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
	  /*   The encodings of adjoining RelativeDistinguishedNames are separated
	   *   by a comma character (',' ASCII 44).
	   */

	  /*   Where there is a multi-valued RDN, the outputs from adjoining
	   *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
	   *   character.
	   */
	  if (k1 != 1)
	    {			/* the first time do not append a comma */
	      if (k2 != 1)
		{		/* adjoining multi-value RDN */
		  STR_APPEND ("+");
		}
	      else
		{
		  STR_APPEND (",");
		}
	    }

	  ldap_desc = oid2ldap_string (oid);
	  printable = _gnutls_x509_oid_data_printable (oid);

	  sizeof_escaped = 2 * len + 1;

	  escaped = gnutls_malloc (sizeof_escaped);
	  if (escaped == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  sizeof_string = 2 * len + 2;	/* in case it is not printable */

	  string = gnutls_malloc (sizeof_string);
	  if (string == NULL)
	    {
	      gnutls_assert ();
	      result = GNUTLS_E_MEMORY_ERROR;
	      goto cleanup;
	    }

	  STR_APPEND (ldap_desc);
	  STR_APPEND ("=");
	  if (printable)
	    result =
	      _gnutls_x509_oid_data2string (oid,
					    value2, len,
					    string, &sizeof_string);
	  else
	    result =
	      _gnutls_x509_data2hex (value2, len, string, &sizeof_string);

	  if (result < 0)
	    {
	      gnutls_assert ();
	      _gnutls_x509_log
		("Found OID: '%s' with value '%s'\n",
		 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped));
	      goto cleanup;
	    }
	  STR_APPEND (str_escape (string, escaped, sizeof_escaped));
	  gnutls_free (string);
	  string = NULL;

	  gnutls_free (escaped);
	  escaped = NULL;
	  gnutls_free (value2);
	  value2 = NULL;

	}
      while (1);

    }
  while (1);

  if (out_str.length >= (unsigned int) *sizeof_buf)
    {
      gnutls_assert ();
      *sizeof_buf = out_str.length + 1;
      result = GNUTLS_E_SHORT_MEMORY_BUFFER;
      goto cleanup;
    }

  if (buf)
    {
      memcpy (buf, out_str.data, out_str.length);
      buf[out_str.length] = 0;
    }
  *sizeof_buf = out_str.length;

  result = 0;

cleanup:
  gnutls_free (value2);
  gnutls_free (string);
  gnutls_free (escaped);
  _gnutls_string_clear (&out_str);
  return result;
}