Reuse previous nonce if outbound proxy realm is set to avoid reauthentication

parent b3012e59
......@@ -62,11 +62,12 @@ BELLESIP_EXPORT void belle_sip_provider_clean_channels(belle_sip_provider_t *p);
* @param request to be updated
* @param resp response to take authentication values from, might be NULL
* @param from_uri optional - an uri to use instead of the from of the request, which can be anonymous.
* @param auth_infos A newly allocated belle_sip_auth_info_t object is added to this list. These object contains useful information like realm and username.
* @param auth_infos optional - A newly allocated belle_sip_auth_info_t object is added to this list. These object contains useful information like realm and username.
* @param realm optional - If an outbound proxy realm is used, nounce can be reused from previous request to avoid re-authentication.
* @returns 0 in case of success,
*
**/
BELLESIP_EXPORT int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_request_t* request,belle_sip_response_t *resp, belle_sip_uri_t *from_uri, belle_sip_list_t** auth_infos);
BELLESIP_EXPORT int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_request_t* request,belle_sip_response_t *resp, belle_sip_uri_t *from_uri, belle_sip_list_t** auth_infos, const char* realm);
/**
* Can be used to simulate network recv error, for tests.
......@@ -110,7 +111,7 @@ BELLESIP_EXPORT int belle_sip_provider_is_rport_enabled(belle_sip_provider_t *pr
/**
* Enable discovery of NAT's public address and port during SIP exchanges.
* When activated, automatic contacts ( see belle_sip_header_contact_set_automatic() )
* When activated, automatic contacts ( see belle_sip_header_contact_set_automatic() )
* will use discovered public IP address and port (if any) instead of local ones.
* NAT public address and port are discovered using received and rport parameters in via header of responses.
* As a result, disabling rport ( see belle_sip_provider_enable_rport() ) will also break this feature.
......
......@@ -72,6 +72,16 @@ BELLESIP_EXPORT int belle_sip_refresher_get_retry_after(const belle_sip_refreshe
*/
BELLESIP_EXPORT void belle_sip_refresher_set_retry_after(belle_sip_refresher_t* refresher, int delay_ms);
/**
* returns realm of the outbound proxy used for authentication, if any
*/
BELLESIP_EXPORT const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher);
/**
* Realm of the outbound proxy used for authentication, if any
*/
BELLESIP_EXPORT void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* realm);
/**
* get current client transaction
* @param refresher object
......
......@@ -78,9 +78,10 @@ BELLESIP_EXPORT belle_sip_refresher_t* belle_sip_client_transaction_create_refre
* <br>This function, update cseq, put route set and try to fill authorization headers. Initial request is not cloned.
* @param transaction . must be in state completed
* @param auth_infos if auth infos cannot be added for an authenticate header,
* @param realm optional - If an outbound proxy realm is used, digestion authentication can be optimized.
* a newly allocated belle_sip_auth_info_t object is added to this list. These object contains useful information like realm and username. May be NULL
* */
BELLESIP_EXPORT belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos);
BELLESIP_EXPORT belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos,const char* realm);
#define BELLE_SIP_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_transaction_t)
#define BELLE_SIP_SERVER_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_server_transaction_t)
......
This diff is collapsed.
......@@ -39,6 +39,7 @@ struct belle_sip_refresher {
belle_sip_refresher_listener_t listener;
belle_sip_source_t* timer;
belle_sip_client_transaction_t* transaction;
char* realm;
int target_expires;
int obtained_expires;
belle_sip_refresher_state_t state;
......@@ -314,6 +315,7 @@ static void destroy(belle_sip_refresher_t *refresher){
belle_sip_provider_remove_internal_sip_listener(refresher->transaction->base.provider,BELLE_SIP_LISTENER(refresher));
belle_sip_object_unref(refresher->transaction);
refresher->transaction=NULL;
if (refresher->realm) belle_sip_free(refresher->realm);
if (refresher->auth_events) refresher->auth_events=belle_sip_list_free_with_data(refresher->auth_events,(void (*)(void*))belle_sip_auth_event_destroy);
}
......@@ -358,7 +360,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
belle_sip_uri_t* preset_route=refresher->transaction->preset_route;
belle_sip_provider_t* prov=refresher->transaction->base.provider;
belle_sip_header_contact_t* contact;
/*first remove timer if any*/
if (expires >=0) {
refresher->target_expires=expires;
......@@ -379,7 +381,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
cseq=belle_sip_message_get_header_by_type(request,belle_sip_header_cseq_t);
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
} else {
request=belle_sip_client_transaction_create_authenticated_request(refresher->transaction,auth_infos);
request=belle_sip_client_transaction_create_authenticated_request(refresher->transaction,auth_infos,refresher->realm);
}
if (requri){
/*case where we are redirected*/
......@@ -401,7 +403,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(expires_header));
}
}
belle_sip_provider_add_authorization(prov,request,old_response,NULL,auth_infos);
belle_sip_provider_add_authorization(prov,request,old_response,NULL,auth_infos,refresher->realm);
} else {
belle_sip_error("Unexpected dialog state [%s] for dialog [%p], cannot refresh [%s]"
,belle_sip_dialog_state_to_string(belle_sip_dialog_get_state(dialog))
......@@ -415,7 +417,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
if (request) belle_sip_object_unref(request);
return -1;
}
refresher->on_io_error=0; /*reset this flag*/
/*update expires in any cases*/
......@@ -434,7 +436,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
belle_sip_header_date_set_time(date,&curtime);
}
}
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
client_transaction->base.is_internal=1;
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),refresher);
......@@ -474,7 +476,7 @@ static int timer_cb(void *user_data, unsigned int events) {
if (refresher->listener) refresher->listener(refresher,refresher->user_data,0, "about to expire");
return BELLE_SIP_STOP;
}
if (belle_sip_refresher_refresh(refresher,refresher->target_expires)==-1){
retry_later(refresher);
}
......@@ -533,13 +535,13 @@ static int set_expires_from_trans(belle_sip_refresher_t* refresher) {
belle_sip_header_contact_t* contact_header;
refresher->obtained_expires=-1;
if (strcmp("REGISTER",belle_sip_request_get_method(request))==0
|| expires_header /*if request has an expire header, refresher can always work*/) {
if (expires_header)
refresher->target_expires = belle_sip_header_expires_get_expires(expires_header);
/*An "expires" parameter on the "Contact" header has no semantics for
* SUBSCRIBE and is explicitly not equivalent to an "Expires" header in
* a SUBSCRIBE request or response.
......@@ -625,14 +627,14 @@ belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* t
belle_sip_transaction_state_t state=belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(transaction));
belle_sip_request_t* request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction));
int is_register=strcmp("REGISTER",belle_sip_request_get_method(request))==0;
refresher = (belle_sip_refresher_t*)belle_sip_object_new(belle_sip_refresher_t);
refresher->transaction=transaction;
refresher->state=stopped;
refresher->number_of_retry=0;
belle_sip_object_ref(transaction);
refresher->retry_after=DEFAULT_RETRY_AFTER;
belle_sip_provider_add_internal_sip_listener(transaction->base.provider,BELLE_SIP_LISTENER(refresher), is_register);
if (set_expires_from_trans(refresher)==-1){
belle_sip_error("Unable to extract refresh value from transaction [%p]",transaction);
......@@ -658,6 +660,21 @@ int belle_sip_refresher_get_retry_after(const belle_sip_refresher_t* refresher){
void belle_sip_refresher_set_retry_after(belle_sip_refresher_t* refresher, int delay_ms) {
refresher->retry_after=delay_ms;
}
const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher){
return refresher->realm;
}
void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* realm) {
if (refresher->realm){
belle_sip_free(refresher->realm);
refresher->realm = NULL;
}
if (realm!=NULL){
refresher->realm=belle_sip_strdup(realm);
}
}
const belle_sip_client_transaction_t* belle_sip_refresher_get_transaction(const belle_sip_refresher_t* refresher) {
return refresher->transaction;
}
......
......@@ -142,7 +142,7 @@ void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t){
* We limit this dead channel reporting to REGISTER transactions, who are unlikely to be unresponded.
**/
belle_sip_warning("Transaction [%p] reporting timeout, reporting to channel.",t);
if (strcmp(belle_sip_request_get_method(t->request),"REGISTER")==0 && belle_sip_channel_notify_timeout(t->channel)==TRUE){
t->timed_out=TRUE;
}else {
......@@ -191,11 +191,11 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
void belle_sip_server_transaction_init(belle_sip_server_transaction_t *t, belle_sip_provider_t *prov,belle_sip_request_t *req){
const char *branch;
belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via"));
branch=belle_sip_header_via_get_branch(via);
if (branch==NULL){
branch=req->rfc2543_branch;
if (branch==NULL) belle_sip_fatal("No computed branch for RFC2543 style of message, this should never happen.");
if (branch==NULL) belle_sip_fatal("No computed branch for RFC2543 style of message, this should never happen.");
}
t->base.branch_id=belle_sip_strdup(branch);
belle_sip_transaction_init((belle_sip_transaction_t*)t,prov,req);
......@@ -207,7 +207,7 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
belle_sip_header_to_t *to=(belle_sip_header_to_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"to");
belle_sip_dialog_t *dialog=base->dialog;
int status_code;
belle_sip_object_ref(resp);
if (!base->last_response){
belle_sip_hop_t* hop=belle_sip_response_get_return_hop(resp);
......@@ -331,7 +331,7 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
belle_sip_provider_t *prov=t->base.provider;
belle_sip_dialog_t *dialog=t->base.dialog;
int result=-1;
if (t->base.state!=BELLE_SIP_TRANSACTION_INIT){
belle_sip_error("belle_sip_client_transaction_send_request: bad state.");
return -1;
......@@ -347,7 +347,7 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
t->preset_route=outbound_proxy;
belle_sip_object_ref(t->preset_route);
}
if (t->base.request->dialog_queued){
/*this request was created by belle_sip_dialog_create_queued_request().*/
if (belle_sip_dialog_request_pending(dialog)){
......@@ -362,11 +362,11 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
belle_sip_dialog_update_request(dialog,req);
}
}
if (dialog){
belle_sip_dialog_update(dialog,(belle_sip_transaction_t*)t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t));
}
if (!t->next_hop) {
if (t->preset_route) {
t->next_hop=belle_sip_hop_new_from_uri(t->preset_route);
......@@ -469,7 +469,7 @@ static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_
belle_sip_client_transaction_t *t=(belle_sip_client_transaction_t*)l;
belle_sip_io_error_event_t ev;
belle_sip_transaction_state_t tr_state=belle_sip_transaction_get_state((belle_sip_transaction_t*)t);
belle_sip_message("transaction [%p] channel state changed to [%s]"
,t
,belle_sip_channel_state_to_string(state));
......@@ -493,7 +493,7 @@ static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_
}
if (t->base.timed_out)
notify_timeout((belle_sip_transaction_t*)t);
belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
break;
default:
......@@ -530,7 +530,7 @@ void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, bell
if (!via){
belle_sip_fatal("belle_sip_client_transaction_init(): No via in request.");
}
if (strcmp(belle_sip_request_get_method(req),"CANCEL")!=0){
obj->base.branch_id=belle_sip_strdup_printf(BELLE_SIP_BRANCH_MAGIC_COOKIE ".%s",belle_sip_random_token(token,sizeof(token)));
belle_sip_header_via_set_branch(via,obj->base.branch_id);
......@@ -544,7 +544,7 @@ belle_sip_refresher_t* belle_sip_client_transaction_create_refresher(belle_sip_c
return belle_sip_refresher_new(t);
}
belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos) {
belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos,const char* realm) {
belle_sip_request_t* initial_request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t));
belle_sip_request_t* req=belle_sip_request_clone_with_body(initial_request);
belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
......@@ -562,7 +562,7 @@ belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(b
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
/*put auth header*/
belle_sip_provider_add_authorization(t->base.provider,req,t->base.last_response,NULL,auth_infos);
belle_sip_provider_add_authorization(t->base.provider,req,t->base.last_response,NULL,auth_infos,realm);
return req;
}
......@@ -320,9 +320,9 @@ static endpoint_t* create_endpoint(const char *ip, int port,const char* transpor
endpoint->listener_callbacks=listener_callbacks;
endpoint->lp=belle_sip_stack_create_listening_point(endpoint->stack,ip,port,transport);
endpoint->connection_family=AF_INET;
if (endpoint->lp) belle_sip_object_ref(endpoint->lp);
endpoint->provider=belle_sip_stack_create_provider(endpoint->stack,endpoint->lp);
belle_sip_provider_add_sip_listener(endpoint->provider,(endpoint->listener=belle_sip_listener_create_from_callbacks(endpoint->listener_callbacks,endpoint)));
sprintf(endpoint->nonce,"%p",endpoint); /*initial nonce*/
......@@ -363,7 +363,7 @@ static void refresher_base_with_body(endpoint_t* client
uint64_t end;
if (client->expire_in_contact) belle_sip_header_contact_set_expires(contact,1);
dest_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_listening_point_get_uri(server->lp));
if (client->connection_family==AF_INET6)
belle_sip_uri_set_host(dest_uri,"::1");
......@@ -403,7 +403,7 @@ static void refresher_base_with_body(endpoint_t* client
} else {
CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredOne,1,1000));
/*update cseq*/
req=belle_sip_client_transaction_create_authenticated_request(trans,NULL);
req=belle_sip_client_transaction_create_authenticated_request(trans,NULL,NULL);
belle_sip_object_unref(trans);
trans=belle_sip_provider_create_client_transaction(client->provider,req);
belle_sip_object_ref(trans);
......@@ -490,7 +490,7 @@ static void subscribe_test(void) {
server = create_udp_endpoint(6788,&server_callbacks);
server->expire_in_contact=0;
server->auth=digest_auth;
dest_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_listening_point_get_uri(server->lp));
belle_sip_uri_set_host(dest_uri,"127.0.0.1");
destination_route=belle_sip_header_route_create(belle_sip_header_address_create(NULL,dest_uri));
......@@ -516,7 +516,7 @@ static void subscribe_test(void) {
CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredOne,1,1000));
req=belle_sip_client_transaction_create_authenticated_request(trans,NULL);
req=belle_sip_client_transaction_create_authenticated_request(trans,NULL,NULL);
belle_sip_object_unref(trans);
trans=belle_sip_provider_create_client_transaction(client->provider,req);
belle_sip_object_ref(trans);
......@@ -629,7 +629,7 @@ static int register_test_with_interfaces(const char *transport, const char *clie
client = create_endpoint(client_ip,3452,transport,&client_callbacks);
client->connection_family=connection_family;
client->register_count=1;
server = create_endpoint(server_ip,6788,transport,&server_callbacks);
server->expire_in_contact=client->expire_in_contact=0;
server->auth=none;
......@@ -656,7 +656,7 @@ static int register_test_with_random_port(const char *transport, const char *cli
client = create_endpoint(client_ip,-1,transport,&client_callbacks);
client->connection_family=connection_family;
client->register_count=1;
server = create_endpoint(server_ip,6788,transport,&server_callbacks);
server->expire_in_contact=client->expire_in_contact=0;
server->auth=none;
......
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
......@@ -75,18 +75,22 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
belle_sip_message("process_response_event [%i] [%s]"
,status=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
,belle_sip_response_get_reason_phrase(belle_sip_response_event_get_response(event)));
if (status==401) {
if (status==401){
belle_sip_header_cseq_t* cseq;
belle_sip_client_transaction_t *t;
belle_sip_uri_t *dest;
CU_ASSERT_NOT_EQUAL_FATAL(number_of_challenge,2);
// CU_ASSERT_NOT_EQUAL_FATAL(number_of_challenge,2);
CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_response_event_get_client_transaction(event)); /*require transaction mode*/
dest=belle_sip_client_transaction_get_route(belle_sip_response_event_get_client_transaction(event));
request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(belle_sip_response_event_get_client_transaction(event)));
cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CSEQ);
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
CU_ASSERT_TRUE_FATAL(belle_sip_provider_add_authorization(prov,request,belle_sip_response_event_get_response(event),NULL,NULL));
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION);
CU_ASSERT_TRUE_FATAL(belle_sip_provider_add_authorization(prov,request,belle_sip_response_event_get_response(event),NULL,NULL,auth_domain));
t=belle_sip_provider_create_client_transaction(prov,request);
belle_sip_client_transaction_send_request_to(t,dest);
number_of_challenge++;
......@@ -186,7 +190,7 @@ int register_init(void) {
stack=belle_sip_stack_new(NULL);
lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"UDP");
prov=belle_sip_stack_create_provider(stack,lp);
lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7060,"TCP");
belle_sip_provider_add_listening_point(prov,lp);
lp=belle_sip_stack_create_listening_point(stack,"0.0.0.0",7061,"TLS");
......@@ -236,9 +240,7 @@ void unregister_user(belle_sip_stack_t * stack
belle_sip_header_expires_set_expires(expires_header,0);
if (use_transaction){
belle_sip_client_transaction_t *t;
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
belle_sip_provider_add_authorization(prov,req,NULL,NULL,NULL); /*just in case*/
belle_sip_provider_add_authorization(prov,req,NULL,NULL,NULL,NULL); /*just in case*/
t=belle_sip_provider_create_client_transaction(prov,req);
belle_sip_client_transaction_send_request(t);
}else belle_sip_provider_send_request(prov,req);
......@@ -250,19 +252,19 @@ void unregister_user(belle_sip_stack_t * stack
}
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
,belle_sip_provider_t *prov
,const char *transport
,int use_transaction
,const char* username
,const char* domain
,const char* outbound_proxy
,int success_expected) {
,belle_sip_provider_t *prov
,const char *transport
,int use_transaction
,const char* username
,const char* domain
,const char* outbound_proxy
,int success_expected) {
belle_sip_request_t *req,*copy;
char identity[256];
char uri[256];
int i;
char *outbound=NULL;
number_of_challenge=0;
if (transport)
snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
......@@ -272,7 +274,7 @@ belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
belle_sip_error("No TLS support, test skipped.");
return NULL;
}
if (outbound_proxy){
if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
......@@ -281,14 +283,14 @@ belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
req=belle_sip_request_create(
belle_sip_uri_parse(uri),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
belle_sip_header_to_create2(identity,NULL),
belle_sip_header_via_new(),
70);
belle_sip_uri_parse(uri),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
belle_sip_header_to_create2(identity,NULL),
belle_sip_header_via_new(),
70);
is_register_ok=0;
io_error_count=0;
using_transaction=0;
......@@ -332,7 +334,7 @@ belle_sip_request_t* register_user(belle_sip_stack_t * stack
static void register_with_outbound(const char *transport, int use_transaction,const char* outbound ) {
belle_sip_request_t *req;
req=register_user(stack, prov, transport,use_transaction,"tester",outbound);
if (req) {
unregister_user(stack,prov,req,use_transaction);
......@@ -421,18 +423,18 @@ static void test_bad_request(void) {
cbs.process_io_error=bad_req_process_io_error;
cbs.process_response_event=bad_req_process_response_event;
bad_req_listener = belle_sip_listener_create_from_callbacks(&cbs,&bad_request_response_received);
req=belle_sip_request_create(
BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(route_address)))),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2("sip:toto@titi.com",BELLE_SIP_RANDOM_TAG),
to,
belle_sip_header_via_new(),
70);
BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_header_address_get_uri(route_address)))),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2("sip:toto@titi.com",BELLE_SIP_RANDOM_TAG),
to,
belle_sip_header_via_new(),
70);
belle_sip_uri_set_transport_param(belle_sip_header_address_get_uri(route_address),"tcp");
route = belle_sip_header_route_create(route_address);
......@@ -448,7 +450,7 @@ static void test_bad_request(void) {
CU_ASSERT_TRUE(bad_request_response_received==1);
belle_sip_provider_remove_sip_listener(prov,bad_req_listener);
belle_sip_object_unref(bad_req_listener);
belle_sip_listening_point_clean_channels(lp);
}
......@@ -559,6 +561,125 @@ static void register_dns_load_balancing(void) {
if (req) belle_sip_object_unref(req);
}
static void process_message_response_event(void *user_ctx, const belle_sip_response_event_t *event){
int status;
BELLESIP_UNUSED(user_ctx);
CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_response_event_get_response(event));
belle_sip_message("process_response_event [%i] [%s]"
,status=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
,belle_sip_response_get_reason_phrase(belle_sip_response_event_get_response(event)));
if (status >= 200){
is_register_ok=status;
belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
}
}
static belle_sip_request_t* send_message(belle_sip_request_t *initial_request, const char* realm){
int i;
int io_error_count=0;
belle_sip_request_t *message_request=NULL;
belle_sip_request_t *clone_request=NULL;
// belle_sip_header_authorization_t * h=NULL;
is_register_ok = 0;
message_request=belle_sip_request_create(
belle_sip_uri_parse("sip:sip.linphone.org;transport=tcp")
,"MESSAGE"
,belle_sip_provider_create_call_id(prov)
,belle_sip_header_cseq_create(22,"MESSAGE")
,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(initial_request), belle_sip_header_from_t)
,belle_sip_header_to_parse("To: sip:marie@sip.linphone.org")
,belle_sip_header_via_new()
,70);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
belle_sip_provider_add_authorization(prov,message_request,NULL,NULL,NULL,realm);
// h = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(message_request), belle_sip_header_authorization_t);
/*if a matching authorization was found, use it as a proxy authorization*/
// if (h != NULL){
// belle_sip_header_set_name(BELLE_SIP_HEADER(h), BELLE_SIP_PROXY_AUTHORIZATION);
// }
clone_request = (belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)message_request));
belle_sip_client_transaction_send_request_to(belle_sip_provider_create_client_transaction(prov,message_request),NULL);
for(i=0; i<2 && io_error_count==0 &&is_register_ok==0;i++)
belle_sip_stack_sleep(stack,5000);
return clone_request;
}
static void reuse_nonce(void) {
belle_sip_request_t *register_request;
register_request=register_user_at_domain(stack, prov, "tcp",1,"marie","sip.linphone.org",NULL);
if (register_request) {
char * first_nonce_used;
belle_sip_header_authorization_t * h = NULL;
belle_sip_request_t *message_request;
listener_callbacks.process_dialog_terminated=process_dialog_terminated;
listener_callbacks.process_io_error=process_io_error;
listener_callbacks.process_request_event=process_request_event;
listener_callbacks.process_response_event=process_message_response_event;
listener_callbacks.process_timeout=process_timeout;
listener_callbacks.process_transaction_terminated=process_transaction_terminated;
listener_callbacks.process_auth_requested=process_auth_requested;
listener_callbacks.listener_destroyed=NULL;
listener=belle_sip_listener_create_from_callbacks(&listener_callbacks,NULL);
belle_sip_provider_add_sip_listener(prov,BELLE_SIP_LISTENER(listener));
/*currently only one nonce should have been used (the one for the REGISTER)*/
CU_ASSERT_EQUAL(belle_sip_list_size(prov->auth_contexts), 1);
/*this should reuse previous nonce*/
message_request=send_message(register_request, auth_domain);
CU_ASSERT_EQUAL(is_register_ok, 404);
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
));
CU_ASSERT_PTR_NOT_NULL_FATAL(h);
CU_ASSERT_EQUAL(2, belle_sip_header_authorization_get_nonce_count(h));
first_nonce_used = belle_sip_strdup(belle_sip_header_authorization_get_nonce(h));
belle_sip_object_unref(message_request);
/*new nonce should be created when not using outbound proxy realm*/
message_request=send_message(register_request, NULL);
CU_ASSERT_EQUAL(is_register_ok, 407);
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(