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;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment