コード例 #1
0
static void test_escaped_parameter(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sip:[email protected];pa%3Dram=aa%40bb:5060[];o%40");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(L_uri), "pa=ram"), "aa@bb:5060[]");
	CU_ASSERT_TRUE(belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(L_uri), "o@"));
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
コード例 #2
0
ファイル: belle_sip_uri_impl.c プロジェクト: ormast/belle-sip
/*
 * RFC 3261            SIP: Session Initiation Protocol           June 2002
 * 19.1.4 URI Comparison

   Some operations in this specification require determining whether two
   SIP or SIPS URIs are equivalent.  In this specification, registrars
   need to compare bindings in Contact URIs in REGISTER requests (see
   Section 10.3.).  SIP and SIPS URIs are compared for equality
   according to the following rules:
*/
int belle_sip_uri_equals(const belle_sip_uri_t* uri_a,const belle_sip_uri_t* uri_b) {
	const belle_sip_list_t *	params;
	const char* b_param;
	const char* a_param;
/*
      o  A SIP and SIPS URI are never equivalent.
*/
	if (belle_sip_uri_is_secure(uri_a)!=belle_sip_uri_is_secure(uri_b)) {
		return 0;
	}
/*
	o  Comparison of the userinfo of SIP and SIPS URIs is case-
         sensitive.  This includes userinfo containing passwords or
         formatted as telephone-subscribers.  Comparison of all other
         components of the URI is case-insensitive unless explicitly
         defined otherwise.
*/
	if (uri_a->user && uri_b->user) {
		if (IS_EQUAL(uri_a->user,uri_b->user)) return 0;
	} else if (uri_a->user != uri_a->user) {
		return 0;
	}
/*
      o  The ordering of parameters and header fields is not significant
         in comparing SIP and SIPS URIs.

      o  Characters other than those in the "reserved" set (see RFC 2396
         [5]) are equivalent to their ""%" HEX HEX" encoding.

      o  An IP address that is the result of a DNS lookup of a host name
         does not match that host name.

      o  For two URIs to be equal, the user, password, host, and port
         components must match.
*/
		if (!uri_a->host || !uri_b->host) {
			return 0;
		} else if  (IS_EQUAL_CASE(uri_a->host,uri_b->host)) {
			return 0;
		}
		if (uri_a->port !=uri_b->port) return 0;
/*
         A URI omitting the user component will not match a URI that
         includes one.  A URI omitting the password component will not
         match a URI that includes one.

         A URI omitting any component with a default value will not
         match a URI explicitly containing that component with its
         default value.  For instance, a URI omitting the optional port
         component will not match a URI explicitly declaring port 5060.
         The same is true for the transport-parameter, ttl-parameter,
         user-parameter, and method components.

            Defining sip:user@host to not be equivalent to
            sip:user@host:5060 is a change from RFC 2543.  When deriving
            addresses from URIs, equivalent addresses are expected from
            equivalent URIs.  The URI sip:user@host:5060 will always
            resolve to port 5060.  The URI sip:user@host may resolve to
            other ports through the DNS SRV mechanisms detailed in [4].

      o  URI uri-parameter components are compared as follows:

         -  Any uri-parameter appearing in both URIs must match.
*/
/*
 *         -  A user, ttl, or method uri-parameter appearing in only one
            URI never matches, even if it contains the default value.
           -  A URI that includes an maddr parameter will not match a URI
            that contains no maddr parameter.
 * */
		PARAM_CASE_CMP(uri_a,uri_b,"transport")
		PARAM_CASE_CMP(uri_a,uri_b,"user")
		PARAM_CASE_CMP(uri_a,uri_b,"ttl")
		PARAM_CASE_CMP(uri_a,uri_b,"method")
		PARAM_CASE_CMP(uri_a,uri_b,"maddr")


		for(params=belle_sip_parameters_get_parameters((belle_sip_parameters_t*) uri_a);params!=NULL;params=params->next) {
			if ((b_param=belle_sip_parameters_get_parameter((belle_sip_parameters_t*) uri_b,(const char*)params->data)) !=NULL) {
				if (IS_EQUAL_CASE(b_param,(const char*)params->data)) return 0;
			}

		}

 /*


         -  All other uri-parameters appearing in only one URI are
            ignored when comparing the URIs.
*/
/* *fixme ignored for now*/
/*
      o  URI header components are never ignored.  Any present header
         component MUST be present in both URIs and match for the URIs
         to match.  The matching rules are defined for each header field
         in Section 20.
 */
	return 1;
}
コード例 #3
0
ファイル: belle_sip_uri_impl.c プロジェクト: ormast/belle-sip
const char* belle_sip_uri_get_header(const belle_sip_uri_t* uri,const char* name) {
	return belle_sip_parameters_get_parameter(uri->header_list,name);
}
コード例 #4
0
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
	belle_sip_request_t* req = belle_sip_request_event_get_request(event);
	belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req);
	belle_sip_header_address_t* address;
	belle_sip_header_from_t* from_header;
	belle_sip_header_content_type_t* content_type;
	belle_sip_response_t* resp;
	int errcode=500;
	belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
	belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
	belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t);
	char* from;
	bool_t plain_text=FALSE;
	bool_t external_body=FALSE;
	bool_t cipher_xml=FALSE;
	bool_t rcs_filetransfer=FALSE;
	uint8_t *decryptedMessage = NULL;

	from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t);
	content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
	/* check if we have a xml/cipher message to be decrypted */
	if (content_type && (cipher_xml=is_cipher_xml(content_type))) {
		/* access the zrtp cache to get keys needed to decipher the message */
		LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
		FILE *CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+");
		if (CACHEFD == NULL) {
			ms_warning("Unable to access ZRTP ZID cache to decrypt message");
			goto error;
		} else {
			size_t cacheSize;
			char *cacheString;
			int retval;
			xmlDocPtr cacheXml;
			
			cacheString=ms_load_file_content(CACHEFD, &cacheSize);
			if (!cacheString){
				ms_warning("Unable to load content of ZRTP ZID cache to decrypt message");
				goto error;
			}
			cacheString[cacheSize] = '\0';
			cacheSize += 1;
			fclose(CACHEFD);
			cacheXml = xmlParseDoc((xmlChar*)cacheString);
			ms_free(cacheString);
			retval = lime_decryptMultipartMessage(cacheXml, (uint8_t *)belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)), &decryptedMessage);
			if (retval != 0) {
				ms_warning("Unable to decrypt message, reason : %s - op [%p]", lime_error_code_to_string(retval), op);
				free(decryptedMessage);
				xmlFreeDoc(cacheXml);
				errcode = 488;
				goto error;
			} else {
				/* dump updated cache to a string */
				xmlChar *xmlStringOutput;
				int xmlStringLength;
				xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
				/* write it to the cache file */
				CACHEFD = fopen(lc->zrtp_secrets_cache, "wb+");
				if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){
					ms_warning("Fail to write cache");
				}
				xmlFree(xmlStringOutput);
				fclose(CACHEFD);
			}

			xmlFreeDoc(cacheXml);
		}

	}

	rcs_filetransfer=is_rcs_filetransfer(content_type);
	if (content_type && ((plain_text=is_plain_text(content_type))
						|| (external_body=is_external_body(content_type))
						|| (decryptedMessage!=NULL) 
						|| rcs_filetransfer)) {
		SalMessage salmsg;
		char message_id[256]={0};
	
		if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
		op->pending_server_trans=server_transaction;
		belle_sip_object_ref(op->pending_server_trans);
	
		address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
				,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
		from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
		snprintf(message_id,sizeof(message_id)-1,"%s%i"
				,belle_sip_header_call_id_get_call_id(call_id)
				,belle_sip_header_cseq_get_seq_number(cseq));
		salmsg.from=from;
		/* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/
		if (cipher_xml) {
			salmsg.text = (char *)decryptedMessage;
		} else { /* message body wasn't ciphered */
			salmsg.text=(plain_text||rcs_filetransfer)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
		}
		salmsg.url=NULL;
		salmsg.content_type = NULL;
		if (rcs_filetransfer) { /* if we have a rcs file transfer, set the type, message body (stored in salmsg.text) contains all needed information to retrieve the file */
			salmsg.content_type = "application/vnd.gsma.rcs-ft-http+xml";
		}
		if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
			size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
			salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
			((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
		}
		salmsg.message_id=message_id;
		salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
		op->base.root->callbacks.text_received(op,&salmsg);

		free(decryptedMessage);
		belle_sip_object_unref(address);
		belle_sip_free(from);
		if (salmsg.url) ms_free((char*)salmsg.url);
	} else if (content_type && is_im_iscomposing(content_type)) {
		SalIsComposing saliscomposing;
		address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
				,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
		from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
		saliscomposing.from=from;
		saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
		op->base.root->callbacks.is_composing_received(op,&saliscomposing);
		resp = belle_sip_response_create_from_request(req,200);
		belle_sip_server_transaction_send_response(server_transaction,resp);
		belle_sip_object_unref(address);
		belle_sip_free(from);
	} else {
		ms_error("Unsupported MESSAGE (content-type not recognized)");
		resp = belle_sip_response_create_from_request(req,415);
		add_message_accept((belle_sip_message_t*)resp);
		belle_sip_server_transaction_send_response(server_transaction,resp);
		sal_op_release(op);
		return;
	}
	return;
error:
	resp = belle_sip_response_create_from_request(req, errcode);
	belle_sip_server_transaction_send_response(server_transaction,resp);
	sal_op_release(op);
}
コード例 #5
0
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
	belle_sip_request_t* req = belle_sip_request_event_get_request(event);
	belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req);
	belle_sip_header_address_t* address;
	belle_sip_header_from_t* from_header;
	belle_sip_header_content_type_t* content_type;
	belle_sip_response_t* resp;
	belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
	belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
	belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t);
	char* from;
	bool_t plain_text=FALSE;
	bool_t external_body=FALSE;

	from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t);
	content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
	if (content_type && ((plain_text=is_plain_text(content_type))
						|| (external_body=is_external_body(content_type)))) {
		SalMessage salmsg;
		char message_id[256]={0};
	
		if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
		op->pending_server_trans=server_transaction;
		belle_sip_object_ref(op->pending_server_trans);
	
		address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
				,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
		from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
		snprintf(message_id,sizeof(message_id)-1,"%s%i"
				,belle_sip_header_call_id_get_call_id(call_id)
				,belle_sip_header_cseq_get_seq_number(cseq));
		salmsg.from=from;
		salmsg.text=plain_text?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL;
		salmsg.url=NULL;
		if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) {
			size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"));
			salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
			((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
		}
		salmsg.message_id=message_id;
		salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
		op->base.root->callbacks.text_received(op,&salmsg);
		belle_sip_object_unref(address);
		belle_sip_free(from);
		if (salmsg.url) ms_free((char*)salmsg.url);
	} else if (content_type && is_im_iscomposing(content_type)) {
		SalIsComposing saliscomposing;
		address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
				,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
		from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
		saliscomposing.from=from;
		saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
		op->base.root->callbacks.is_composing_received(op,&saliscomposing);
		resp = belle_sip_response_create_from_request(req,200);
		belle_sip_server_transaction_send_response(server_transaction,resp);
		belle_sip_object_unref(address);
		belle_sip_free(from);
	} else {
		ms_error("Unsupported MESSAGE with content type [%s/%s]",belle_sip_header_content_type_get_type(content_type)
				,belle_sip_header_content_type_get_subtype(content_type));
		resp = belle_sip_response_create_from_request(req,415);
		add_message_accept((belle_sip_message_t*)resp);
		belle_sip_server_transaction_send_response(server_transaction,resp);
		return;
	}
}
コード例 #6
0
const char * sal_address_get_uri_param(const SalAddress *addr, const char *name) {
	belle_sip_parameters_t* parameters = BELLE_SIP_PARAMETERS(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)));
	return belle_sip_parameters_get_parameter(parameters, name);
}
コード例 #7
0
const char * sal_address_get_param(const SalAddress *addr, const char *name) {
	belle_sip_parameters_t* parameters = BELLE_SIP_PARAMETERS(addr);
	return belle_sip_parameters_get_parameter(parameters, name);
}