diff --git a/include/belle-sip/auth-helper.h b/include/belle-sip/auth-helper.h index bbf328b901253c5768a4b6088c75cae75c51f287..937a3e6a8b336cd28c2c48aa790ef8f01e737e78 100644 --- a/include/belle-sip/auth-helper.h +++ b/include/belle-sip/auth-helper.h @@ -56,6 +56,12 @@ BELLESIP_EXPORT belle_http_header_authorization_t* belle_http_auth_helper_create */ BELLESIP_EXPORT belle_sip_header_proxy_authorization_t* belle_sip_auth_helper_create_proxy_authorization(const belle_sip_header_proxy_authenticate_t* proxy_authentication); +/** + * return size which depends on algorithm + * @return 0 if failed + */ +BELLESIP_EXPORT int belle_sip_auth_define_size(const char* algo); + /** * compute and set response value according to parameters * HA1=MD5(username:realm:passwd) @@ -95,6 +101,12 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha1_for_algorithm(const char* * */ BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2(const char* method,const char* uri, char ha2[33]); +/* + * compute HA2 (NULL terminated) + * HA2=MD5(method:uri) or SHA-256(method:uri) + * return 0 in case of success + * */ +BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2_for_algorithm(const char* method,const char* uri, char *ha2, size_t size, const char* algo); /* * compute response(NULL terminated) * res=MD5(ha1:nonce:ha2) @@ -102,6 +114,12 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2(const char* method,const c * */ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response(const char* ha1,const char* nonce, const char* ha2, char response[33]); +/* + * compute response(NULL terminated) + * res=MD5(ha1:nonce:ha2) or SHA-256(ha1:nonce:ha2) + * return 0 in case of success + * */ +BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_for_algorithm(const char* ha1,const char* nonce, const char* ha2, char *response, size_t size, const char* algo); /* * compute response(NULL terminated) * res=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2) @@ -115,7 +133,19 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth( const char* , const char* ha2 , char response[33]); - +/* + * compute response(NULL terminated) + * res=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2) or SHA-256(HA1:nonce:nonce_count:cnonce:qop:HA2) + * return 0 in case of success + * */ +BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(const char* ha1 + , const char* nonce + , unsigned int nonce_count + , const char* cnonce + , const char* qop + , const char* ha2 + , char *response + , size_t size, const char* algo); /*TLS client certificate auth*/ /** diff --git a/include/belle-sip/provider.h b/include/belle-sip/provider.h index ff9a64b5c2f4f48420999dbae4bc246ee1df2bea..8ffb526e59e8a7445ef9b02f330e3f71592dc615 100644 --- a/include/belle-sip/provider.h +++ b/include/belle-sip/provider.h @@ -56,6 +56,19 @@ BELLESIP_EXPORT void belle_sip_provider_send_response(belle_sip_provider_t *p, b BELLESIP_EXPORT void belle_sip_provider_clean_channels(belle_sip_provider_t *p); +/** + * Add auth info to the request if found + * @param p object + * @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 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_for_algorithm(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, const char* algorithm); + /** * Add auth info to the request if found * @param p object diff --git a/include/belle-sip/refresher.h b/include/belle-sip/refresher.h index 5acf1aa9954c86b022c8f48f0e39f6d2ab840e88..d6860e8ac9120b3813443ff898b9255b1c368592 100644 --- a/include/belle-sip/refresher.h +++ b/include/belle-sip/refresher.h @@ -79,11 +79,21 @@ BELLESIP_EXPORT void belle_sip_refresher_set_retry_after(belle_sip_refresher_t* */ BELLESIP_EXPORT const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher); +/** + * returns algorithm of the outbound proxy used for authentication, if any + */ +BELLESIP_EXPORT const char* belle_sip_refresher_get_algorithm(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); +/** + * algorithm of the outbound proxy used for authentication, if any + */ +BELLESIP_EXPORT void belle_sip_refresher_set_algorithm(belle_sip_refresher_t* refresher, const char* algorithm); + /** * get current client transaction * @param refresher object diff --git a/include/belle-sip/transaction.h b/include/belle-sip/transaction.h index 28a5aa70292f07f8509891e26818bf5a2f778075..758b65fd46316a6f06c2a0a8ddebddddda0b8f77 100644 --- a/include/belle-sip/transaction.h +++ b/include/belle-sip/transaction.h @@ -83,6 +83,17 @@ BELLESIP_EXPORT belle_sip_refresher_t* belle_sip_client_transaction_create_refre * */ 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); +/** + * Create an authenticated request based on an existing terminated transaction. + * <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. + * @param algo for different algorithm MD5 or SHA-256 + * 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_for_algorithm(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos,const char* realm,const char* algo); + /** * For transactions over unreliable transports, stop retransmissions. This avoids for example to keep sending INVITE retransmissions of a call that has just been terminated, while * keeping the transaction alive in order to eventually let a response being handled, so that the transaction can be cancelled properly. diff --git a/src/auth_helper.c b/src/auth_helper.c index ede40f0a10d254d346ef800e5a8522c84e1ff431..0d96c0ebb5a682abcc089ac4364c89ce6d4d1bff 100644 --- a/src/auth_helper.c +++ b/src/auth_helper.c @@ -74,7 +74,7 @@ belle_sip_header_proxy_authorization_t* belle_sip_auth_helper_create_proxy_autho } static void belle_sip_auth_choose_method(const char* algo,char *ask,uint8_t *out, size_t size){ - if (!strcmp(algo,"MD5")){ + if((algo==NULL)||(!strcmp(algo,"MD5"))){ bctbx_md5((const unsigned char*)ask, strlen(ask), out); } else if(!strcmp(algo,"SHA-256")){ @@ -82,8 +82,22 @@ static void belle_sip_auth_choose_method(const char* algo,char *ask,uint8_t *out } } +int belle_sip_auth_define_size(const char* algo) { + if((algo==NULL)||(!strcmp(algo,"MD5"))){ + return 33; + } + else if(!strcmp(algo,"SHA-256")){ + return 65; + } + else{ + return 0; + } +} + int belle_sip_auth_helper_compute_ha1_for_algorithm(const char* userid,const char* realm,const char* password, char *ha1, size_t size, const char* algo) { - if (!(((size == 33) && (!strcmp(algo,"MD5")))|| ((size == 65) && (!strcmp(algo,"SHA-256"))))) { + size_t compared_size; + compared_size = belle_sip_auth_define_size(algo); + if (compared_size!= size) { belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 "); return -1; } @@ -119,7 +133,9 @@ int belle_sip_auth_helper_compute_ha1(const char* userid,const char* realm,const } int belle_sip_auth_helper_compute_ha2_for_algorithm(const char* method,const char* uri, char *ha2, size_t size, const char* algo) { - if (!(((size == 33) && (!strcmp(algo,"MD5")))|| ((size == 65) && (!strcmp(algo,"SHA-256"))))) { + size_t compared_size; + compared_size = belle_sip_auth_define_size(algo); + if (compared_size!= size) { belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 "); return -1; } @@ -144,7 +160,9 @@ int belle_sip_auth_helper_compute_ha2(const char* method,const char* uri, char h } int belle_sip_auth_helper_compute_response_for_algorithm(const char* ha1,const char* nonce, const char* ha2, char *response, size_t size, const char* algo) { - if (!(((size == 33) && (!strcmp(algo,"MD5")))|| ((size == 65) && (!strcmp(algo,"SHA-256"))))) { + size_t compared_size; + compared_size = belle_sip_auth_define_size(algo); + if (compared_size!= size) { belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 "); return -1; } @@ -177,7 +195,9 @@ int belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(const char* ha , const char* ha2 , char *response , size_t size, const char* algo) { - if (!(((size == 33) && (!strcmp(algo,"MD5")))|| ((size == 65) && (!strcmp(algo,"SHA-256"))))) { + size_t compared_size; + compared_size = belle_sip_auth_define_size(algo); + if (compared_size!= size) { belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 "); return -1; } @@ -216,14 +236,9 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a ,const char* ha1) { size_t size; const char *algo = belle_sip_header_authorization_get_algorithm(authorization); - if (!strcmp(algo,"MD5")){ - size = 33; - } - else if(!strcmp(algo,"SHA-256")){ - size = 65; - } - else{ - belle_sip_error("belle_sip_fill_authorization_header, algorithm is neither MD5 nor SHA-256 "); + size = belle_sip_auth_define_size(algo); + if(!size) { + belle_sip_error("Algorithm [%s] is not correct ", algo); return -1; } diff --git a/src/provider.c b/src/provider.c index 16d0979b1e54bada37d00c13cc6a5d0f9c64a9ee..0b0dc549f753d0bbaab54c3827a2e5d8086e52a8 100644 --- a/src/provider.c +++ b/src/provider.c @@ -1135,8 +1135,8 @@ static void belle_sip_provider_update_or_create_auth_context(belle_sip_provider } -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) { +int belle_sip_provider_add_authorization_for_algorithm(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, const char* algorithm) { belle_sip_header_call_id_t* call_id; belle_sip_list_t* auth_context_iterator; belle_sip_list_t* authenticate_lst; @@ -1147,9 +1147,11 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ belle_sip_auth_event_t* auth_event; authorization_context_t* auth_context; const char* ha1; - char computed_ha1[33]; + char computed_ha1[65]; int result=0; const char* request_method; + size_t size; + const char* algo; /*check params*/ if (!p || !request) { belle_sip_error("belle_sip_provider_add_authorization bad parameters"); @@ -1256,17 +1258,28 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ belle_sip_header_authorization_set_nonce(authorization,auth_context->nonce); belle_sip_header_authorization_set_qop(authorization,auth_context->qop); belle_sip_header_authorization_set_opaque(authorization,auth_context->opaque); - belle_sip_header_authorization_set_algorithm(authorization,auth_context->algorithm); + if(algorithm==NULL){ + belle_sip_header_authorization_set_algorithm(authorization,auth_context->algorithm); + } + else { + belle_sip_header_authorization_set_algorithm(authorization,algorithm); + } + belle_sip_header_authorization_set_uri(authorization,(belle_sip_uri_t*)belle_sip_request_get_uri(request)); if (auth_context->qop){ ++auth_context->nonce_count; belle_sip_header_authorization_set_nonce_count(authorization,auth_context->nonce_count); } - + algo = belle_sip_header_authorization_get_algorithm(authorization); + size = belle_sip_auth_define_size(algo); + if (!size) { + belle_sip_error("Algorithm [%s] is not correct ", algo); + return -1; + } if (auth_event->ha1) { ha1=auth_event->ha1; } else { - belle_sip_auth_helper_compute_ha1(auth_event->userid,auth_context->realm,auth_event->passwd, computed_ha1); + belle_sip_auth_helper_compute_ha1_for_algorithm(auth_event->userid,auth_context->realm,auth_event->passwd, computed_ha1, size, algo); ha1=computed_ha1; } if (belle_sip_auth_helper_fill_authorization(authorization @@ -1291,6 +1304,11 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ return result; } +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) { + belle_sip_provider_add_authorization_for_algorithm(p,request,resp,from_uri,auth_infos,realm,NULL); + return 0; +} void belle_sip_provider_set_recv_error(belle_sip_provider_t *prov, int recv_error) { belle_sip_list_t *lps; belle_sip_list_t *channels; diff --git a/src/refresher.c b/src/refresher.c index 46c04cb54c9db79a376481731926a561f2465c7a..b5a1b82256b5541402ef7ad0273aa01f565ec0cb 100644 --- a/src/refresher.c +++ b/src/refresher.c @@ -56,6 +56,7 @@ struct belle_sip_refresher { timer_purpose_t timer_purpose; unsigned char manual; unsigned int publish_pending; + char* algo; }; static void set_or_update_dialog(belle_sip_refresher_t* refresher, belle_sip_dialog_t* dialog); static int set_expires_from_trans(belle_sip_refresher_t* refresher); @@ -481,7 +482,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher 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,refresher->realm); + request=belle_sip_client_transaction_create_authenticated_request_for_algorithm(refresher->transaction,auth_infos,refresher->realm,refresher->algo); } if (requri){ /*case where we are redirected*/ @@ -523,7 +524,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher } } - belle_sip_provider_add_authorization(prov,request,old_response,NULL,auth_infos,refresher->realm); + belle_sip_provider_add_authorization_for_algorithm(prov,request,old_response,NULL,auth_infos,refresher->realm,refresher->algo); break; } case BELLE_SIP_DIALOG_TERMINATED: { @@ -816,6 +817,10 @@ const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher return refresher->realm; } +const char* belle_sip_refresher_get_algorithm(const belle_sip_refresher_t* refresher){ + return refresher->algo; +} + void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* realm) { if (refresher->realm){ belle_sip_free(refresher->realm); @@ -826,6 +831,16 @@ void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* } } +void belle_sip_refresher_set_algorithm(belle_sip_refresher_t* refresher, const char* algorithm) { + if (refresher->algo){ + belle_sip_free(refresher->algo); + refresher->algo = NULL; + } + if (algorithm!=NULL){ + refresher->algo=belle_sip_strdup(algorithm); + } +} + const belle_sip_client_transaction_t* belle_sip_refresher_get_transaction(const belle_sip_refresher_t* refresher) { return refresher->transaction; } diff --git a/src/transaction.c b/src/transaction.c index 5dea6dcb80022ff678dbde67553a43d82f727e15..3f33a04f9229a34b30cf438f06689bf12badba57 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -663,7 +663,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,const char* realm) { +belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request_for_algorithm(belle_sip_client_transaction_t *t,belle_sip_list_t** auth_infos,const char* realm, const char* algo) { 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); @@ -681,10 +681,13 @@ 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,realm); + belle_sip_provider_add_authorization_for_algorithm(t->base.provider,req,t->base.last_response,NULL,auth_infos,realm,algo); return req; } +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){ + return belle_sip_client_transaction_create_authenticated_request_for_algorithm(t,auth_infos,realm,NULL); +} /* rfc 3265 3.3.4. Dialog creation and termination diff --git a/tester/belle_sip_refresher_tester.c b/tester/belle_sip_refresher_tester.c index 628e0299d3dbcd4509261f6768ad944c9eea012f..0ca60c56b33bd2e39351a680fcbf2351ae39f091 100644 --- a/tester/belle_sip_refresher_tester.c +++ b/tester/belle_sip_refresher_tester.c @@ -22,13 +22,16 @@ #ifndef _MSC_VER #include <sys/time.h> +#include "belle-sip/headers.h" +#include "belle-sip/parameters.h" +#include <stdlib.h> #endif #define USERNAME "toto" #define SIPDOMAIN "sip.linphone.org" #define PASSWD "secret" - +#define ALGOM "MD5" static char publish_body[]= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -83,6 +86,7 @@ typedef struct endpoint { const char* realm; unsigned int max_nc_count; bool_t bad_next_nonce; + const char* algo; } endpoint_t; @@ -112,11 +116,13 @@ static void compute_response(const char* username ,const char* nonce ,const char* method ,const char* uri - ,char response[33] ) { - char ha1[33],ha2[33]; - belle_sip_auth_helper_compute_ha1(username,realm,passwd,ha1); - belle_sip_auth_helper_compute_ha2(method,uri,ha2); - belle_sip_auth_helper_compute_response(ha1,nonce,ha2,response); + ,char* response + ,size_t size + ,const char* algo) { + char ha1[size],ha2[size]; + belle_sip_auth_helper_compute_ha1_for_algorithm(username,realm,passwd,ha1,size,algo); + belle_sip_auth_helper_compute_ha2_for_algorithm(method,uri,ha2,size,algo); + belle_sip_auth_helper_compute_response_for_algorithm(ha1,nonce,ha2,response,size,algo); } static void compute_response_auth_qop(const char* username @@ -128,11 +134,13 @@ static void compute_response_auth_qop(const char* username ,const char* qop ,const char* method ,const char* uri - ,char response[33] ) { - char ha1[33],ha2[33]; - belle_sip_auth_helper_compute_ha1(username,realm,passwd,ha1); - belle_sip_auth_helper_compute_ha2(method,uri,ha2); - belle_sip_auth_helper_compute_response_qop_auth(ha1, nonce,nonce_count, cnonce,qop,ha2,response); + ,char* response + ,size_t size + ,const char* algo) { + char ha1[size],ha2[size]; + belle_sip_auth_helper_compute_ha1_for_algorithm(username,realm,passwd,ha1,size,algo); + belle_sip_auth_helper_compute_ha2_for_algorithm(method,uri,ha2,size,algo); + belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(ha1, nonce,nonce_count, cnonce,qop,ha2,response,size,algo); } #define MAX_NC_COUNT 5 @@ -146,16 +154,33 @@ static void server_process_request_event(void *obj, const belle_sip_request_even belle_sip_header_expires_t* expires; belle_sip_header_authorization_t* authorization; belle_sip_header_via_t* via; - const char* raw_authenticate_digest = "WWW-Authenticate: Digest " - "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; - const char* raw_proxy_authenticate_digest = "Proxy-Authenticate: Digest " - "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; - + const char* raw_authenticate_digest; + const char* raw_proxy_authenticate_digest; + if((!strcmp(endpoint->algo,"MD5"))||(!strcmp(endpoint->algo,"MD_SHA"))){ + raw_authenticate_digest = "WWW-Authenticate: Digest " + "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; + raw_proxy_authenticate_digest = "Proxy-Authenticate: Digest " + "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; + } + else if(!strcmp(endpoint->algo,"SHA-256")){ + raw_authenticate_digest = "WWW-Authenticate: Digest " + "algorithm=SHA-256, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; + raw_proxy_authenticate_digest = "Proxy-Authenticate: Digest " + "algorithm=SHA-256, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; + } + else{ + belle_sip_error("Algorithm of server must be MD5, SHA-256 or MD_SHA, can not be %s", endpoint->algo); + return; + } + belle_sip_header_www_authenticate_t* www_authenticate=NULL; + belle_sip_header_www_authenticate_t* two_www_authenticate=NULL; const char* auth_uri; const char* qop; unsigned char auth_ok=0; - char local_resp[33]; + size_t size; + const char* algo; + const char* algo_ref="SHA-256"; belle_sip_message("caller_process_request_event received [%s] message",belle_sip_request_get_method(belle_sip_request_event_get_request(event))); @@ -176,7 +201,13 @@ static void server_process_request_event(void *obj, const belle_sip_request_even } else { BC_ASSERT_TRUE(BELLE_SIP_OBJECT_IS_INSTANCE_OF(authorization, belle_sip_header_proxy_authorization_t)); } - + algo = belle_sip_header_authorization_get_algorithm(authorization); + size = belle_sip_auth_define_size(algo); + if (!size) { + belle_sip_error("Algorithm [%s] is not correct ", algo); + return; + } + char local_resp[size]; if (qop && strcmp(qop,"auth")==0) { compute_response_auth_qop( belle_sip_header_authorization_get_username(authorization) ,belle_sip_header_authorization_get_realm(authorization) @@ -187,7 +218,9 @@ static void server_process_request_event(void *obj, const belle_sip_request_even ,belle_sip_header_authorization_get_qop(authorization) ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) - ,local_resp); + ,local_resp + ,size + ,algo); } else { /*digest*/ compute_response(belle_sip_header_authorization_get_username(authorization) @@ -196,7 +229,9 @@ static void server_process_request_event(void *obj, const belle_sip_request_even ,endpoint->nonce ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) - ,local_resp); + ,local_resp + ,size + ,algo); } belle_sip_free((void*)auth_uri); @@ -285,8 +320,14 @@ static void server_process_request_event(void *obj, const belle_sip_request_even response_code = 407; } resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),response_code); - if (www_authenticate) - belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(www_authenticate)); + if (www_authenticate){ + if (!strcmp(endpoint->algo,"MD_SHA")){ + two_www_authenticate = BELLE_SIP_HEADER_WWW_AUTHENTICATE(belle_sip_object_clone(BELLE_SIP_OBJECT(www_authenticate))); + belle_sip_header_www_authenticate_set_algorithm(two_www_authenticate, algo_ref); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(two_www_authenticate)); + } + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(www_authenticate)); + } } if (endpoint->received) { via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t); @@ -430,8 +471,8 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client uint64_t begin; 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"); @@ -462,7 +503,7 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client } if (client->realm && - belle_sip_provider_add_authorization(client->provider, req, NULL, NULL,NULL, client->realm)) { + belle_sip_provider_add_authorization_for_algorithm(client->provider, req, NULL, NULL,NULL, client->realm, client->algo)) { } trans=belle_sip_provider_create_client_transaction(client->provider,req); @@ -473,6 +514,8 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client client->refresher = refresher = belle_sip_client_transaction_create_refresher(trans); if (client->realm) belle_sip_refresher_set_realm(client->refresher, client->realm); + if (client->algo) + belle_sip_refresher_set_algorithm(client->refresher, client->algo); } else { if (server->auth == none) { BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.twoHundredOk,1,1000)); @@ -483,7 +526,7 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredSeven,1,1000)); } /*update cseq*/ - req=belle_sip_client_transaction_create_authenticated_request(trans,NULL,NULL); + req=belle_sip_client_transaction_create_authenticated_request_for_algorithm(trans,NULL,NULL,client->algo); belle_sip_object_unref(trans); trans=belle_sip_provider_create_client_transaction(client->provider,req); belle_sip_object_ref(trans); @@ -491,11 +534,12 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.twoHundredOk,1,1000)); } client->refresher= refresher = belle_sip_client_transaction_create_refresher(trans); + belle_sip_refresher_set_algorithm(client->refresher, client->algo); } if (BC_ASSERT_PTR_NOT_NULL(refresher)) { belle_sip_object_unref(trans); belle_sip_refresher_set_listener(refresher,belle_sip_refresher_listener,client); - + begin = belle_sip_time_ms(); BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,client->register_count+(client->early_refresher?1:0),client->register_count*1000 + 1000)); end = belle_sip_time_ms(); @@ -510,6 +554,7 @@ static void refresher_base_with_body(endpoint_t* client , const char* method , belle_sip_header_content_type_t* content_type ,const char* body){ + belle_sip_refresher_t* refresher = refresher_base_with_body2(client, server, method, content_type, body,1); /*unregister twice to make sure refresh operation can be safely cascaded*/ belle_sip_refresher_refresh(refresher,0); @@ -517,8 +562,7 @@ static void refresher_base_with_body(endpoint_t* client BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,client->register_count+1,1000)); BC_ASSERT_EQUAL(client->stat.refreshOk,client->register_count+1,int,"%d"); belle_sip_refresher_stop(refresher); - belle_sip_object_unref(refresher); - + belle_sip_object_unref(refresher); } @@ -533,7 +577,9 @@ static void refresher_base_with_param_and_body(const char* method , auth_mode_t auth_mode , int early_refresher , belle_sip_header_content_type_t* content_type - ,const char* body){ + ,const char* body + ,const char* client_algo + ,const char* server_algo){ belle_sip_listener_callbacks_t client_callbacks; belle_sip_listener_callbacks_t server_callbacks; endpoint_t* client,*server; @@ -546,17 +592,19 @@ static void refresher_base_with_param_and_body(const char* method server = create_udp_endpoint(6788,&server_callbacks); server->expire_in_contact=client->expire_in_contact=expire_in_contact; server->auth=auth_mode; + server->algo=server_algo; + client->algo=client_algo; client->early_refresher=early_refresher; refresher_base_with_body(client,server,method,content_type,body); destroy_endpoint(client); destroy_endpoint(server); } -static void refresher_base_with_param(const char* method, unsigned char expire_in_contact,auth_mode_t auth_mode) { - refresher_base_with_param_and_body(method,expire_in_contact,auth_mode,FALSE,NULL,NULL); +static void refresher_base_with_param(const char* method, unsigned char expire_in_contact,auth_mode_t auth_mode,const char* client_algo,const char* server_algo) { + refresher_base_with_param_and_body(method,expire_in_contact,auth_mode,FALSE,NULL,NULL,client_algo,server_algo); } static void register_test_with_param(unsigned char expire_in_contact,auth_mode_t auth_mode) { - refresher_base_with_param("REGISTER",expire_in_contact,auth_mode); + refresher_base_with_param("REGISTER",expire_in_contact,auth_mode,"MD5","MD5"); } static char *list = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\"\n" @@ -928,12 +976,12 @@ static void register_tcp_test_ipv6_random_port(void){ static void simple_publish(void) { belle_sip_header_content_type_t* content_type=belle_sip_header_content_type_create("application","pidf+xml"); - refresher_base_with_param_and_body("PUBLISH",FALSE,TRUE,FALSE, content_type,publish_body); + refresher_base_with_param_and_body("PUBLISH",FALSE,TRUE,FALSE, content_type,publish_body,"MD5","MD5"); } static void simple_publish_with_early_refresher(void) { belle_sip_header_content_type_t* content_type=belle_sip_header_content_type_create("application","pidf+xml"); - refresher_base_with_param_and_body("PUBLISH",FALSE,TRUE,TRUE, content_type,publish_body); + refresher_base_with_param_and_body("PUBLISH",FALSE,TRUE,TRUE, content_type,publish_body,"MD5","MD5"); }