diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index 12f071740..1aa33c953 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -127,7 +127,7 @@ void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *even /*create SalAuthInfo by copying username and realm from suth event*/ SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ; void sal_add_pending_auth(Sal *sal, SalOp *op); - +void sal_remove_pending_auth(Sal *sal, SalOp *op); void sal_add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status); belle_sip_response_t *sal_create_response_from_request(Sal *sal, belle_sip_request_t *req, int code); diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index 44bd98072..46f1b91e2 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -34,6 +34,11 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher sal_op_set_contact_address(op,(SalAddress*)contact_address); belle_sip_object_unref(contact_address); } + if (belle_sip_refresher_get_auth_events(refresher)) { + if (op->auth_info) sal_auth_info_delete(op->auth_info); + /*only take first one for now*/ + op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data)); + } if(status_code == 200) { /*check service route rfc3608*/ belle_sip_header_service_route_t* service_route; @@ -43,6 +48,9 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher } sal_op_set_service_route(op,(const SalAddress*)service_route_address); if (service_route_address) belle_sip_object_unref(service_route_address); + + sal_remove_pending_auth(op->base.root,op); /*just in case*/ + if (op->auth_info) op->base.root->callbacks.auth_success(op,op->auth_info->realm,op->auth_info->username); op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0); } else if (status_code>=400) { /* from rfc3608, 6.1. @@ -57,14 +65,17 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher sal_op_set_service_route(op,NULL); sal_compute_sal_errors_from_code(status_code,&sal_err,&sal_reason); - if (belle_sip_refresher_get_auth_events(refresher) && (status_code == 401 || status_code==407)) { + if (op->auth_info) { /*add pending auth*/ sal_add_pending_auth(op->base.root,op); - if (op->auth_info) sal_auth_info_delete(op->auth_info); - /*only take first one for now*/ - op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data)); + op->base.root->callbacks.register_failure(op,sal_err,sal_reason,reason_phrase); + if (status_code == 403) { /*in sase of 401 or 407, auth requested already invoked previouly*/ + /*auth previouly pending, probably wrong pasword, give a chance to authenticate again*/ + op->base.root->callbacks.auth_requested(op->base.root,op->auth_info); + } } - op->base.root->callbacks.register_failure(op,sal_err,sal_reason,reason_phrase); + } else { + ms_warning("Register refresher know what to do with this status code"); } } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index fa0ed87a1..778ee8ce7 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -894,7 +894,13 @@ static void ping_reply(SalOp *op){ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) { LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,sai->realm,sai->username); - if (ai) { + if (ai && ai->works==FALSE && ai->usecount>=1){ + /*Better is to stop (implemeted below in else statement), and retry later*/ + if (ms_time(NULL)-ai->last_use_time>30){ + ai->usecount=0; /*so that we can allow to retry */ + } + } + if (ai && (ai->works || ai->usecount<1)){ sai->userid=ai->userid?ai->userid:ai->username; sai->password=ai->passwd; sai->ha1=ai->ha1; diff --git a/tester/register_tester.c b/tester/register_tester.c index 95b30154d..c1b3e6230 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -260,6 +260,27 @@ static void authenticated_register_with_late_credentials(){ linphone_core_destroy(lc); } +static void authenticated_register_with_wrong_credentials(){ + LinphoneCoreVTable v_table; + LinphoneCore* lc; + stats stat; + stats* counters; + LCSipTransports transport = {5070,5070,0,5071}; + LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,"wrong passwd",NULL,auth_domain); /*create authentication structure from identity*/ + char route[256]; + sprintf(route,"sip:%s",test_route); + memset (&v_table,0,sizeof(v_table)); + v_table.registration_state_changed=registration_state_changed; + v_table.auth_info_requested=auth_info_requested2; + lc = linphone_core_new(&v_table,NULL,NULL,NULL); + linphone_core_set_user_data(lc,&stat); + linphone_core_add_auth_info(lc,info); /*add wrong authentication info to LinphoneCore*/ + counters = (stats*)linphone_core_get_user_data(lc); + register_with_refresh_base_2(lc,TRUE,auth_domain,route,TRUE,transport); + CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,1); + linphone_core_destroy(lc); +} + static LinphoneCore* configure_lc(LinphoneCoreVTable* v_table) { return configure_lc_from(v_table, liblinphone_tester_file_prefix, "multi_account_lrc", 3); } @@ -419,6 +440,7 @@ test_t register_tests[] = { { "Simple authenticated register", simple_authenticated_register }, { "Ha1 authenticated register", ha1_authenticated_register }, { "Digest auth without initial credentials", authenticated_register_with_no_initial_credentials }, + { "Digest auth with wrong credentials", authenticated_register_with_wrong_credentials }, { "Authenticated register with late credentials", authenticated_register_with_late_credentials }, { "Register with refresh", simple_register_with_refresh }, { "Authenticated register with refresh", simple_auth_register_with_refresh },