Commit 9b728847 authored by Danmei Chen's avatar Danmei Chen

add choice of algorithm in suite refrensher

parent e2be5d96
...@@ -56,6 +56,12 @@ BELLESIP_EXPORT belle_http_header_authorization_t* belle_http_auth_helper_create ...@@ -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); 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 * compute and set response value according to parameters
* HA1=MD5(username:realm:passwd) * HA1=MD5(username:realm:passwd)
...@@ -95,6 +101,12 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha1_for_algorithm(const char* ...@@ -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]); 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) * compute response(NULL terminated)
* res=MD5(ha1:nonce:ha2) * res=MD5(ha1:nonce:ha2)
...@@ -102,6 +114,12 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2(const char* method,const c ...@@ -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]); 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) * compute response(NULL terminated)
* res=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2) * 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* ...@@ -115,7 +133,19 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth( const char*
, const char* ha2 , const char* ha2
, char response[33]); , 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*/ /*TLS client certificate auth*/
/** /**
......
...@@ -56,6 +56,19 @@ BELLESIP_EXPORT void belle_sip_provider_send_response(belle_sip_provider_t *p, b ...@@ -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); 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 * Add auth info to the request if found
* @param p object * @param p object
......
...@@ -79,11 +79,21 @@ BELLESIP_EXPORT void belle_sip_refresher_set_retry_after(belle_sip_refresher_t* ...@@ -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); 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 * 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); 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 * get current client transaction
* @param refresher object * @param refresher object
......
...@@ -83,6 +83,17 @@ BELLESIP_EXPORT belle_sip_refresher_t* belle_sip_client_transaction_create_refre ...@@ -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); 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 * 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. * keeping the transaction alive in order to eventually let a response being handled, so that the transaction can be cancelled properly.
......
...@@ -74,7 +74,7 @@ belle_sip_header_proxy_authorization_t* belle_sip_auth_helper_create_proxy_autho ...@@ -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){ 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); bctbx_md5((const unsigned char*)ask, strlen(ask), out);
} }
else if(!strcmp(algo,"SHA-256")){ 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 ...@@ -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) { 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 "); belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 ");
return -1; return -1;
} }
...@@ -119,7 +133,9 @@ int belle_sip_auth_helper_compute_ha1(const char* userid,const char* realm,const ...@@ -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) { 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 "); belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 ");
return -1; return -1;
} }
...@@ -144,7 +160,9 @@ int belle_sip_auth_helper_compute_ha2(const char* method,const char* uri, char h ...@@ -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) { 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 "); belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 ");
return -1; return -1;
} }
...@@ -177,7 +195,9 @@ int belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(const char* ha ...@@ -177,7 +195,9 @@ int belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(const char* ha
, const char* ha2 , const char* ha2
, char *response , char *response
, size_t size, const char* algo) { , 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 "); belle_sip_error("belle_sip_fill_authorization_header, size of ha1 must be 33 when MD5 or 65 when SHA-256 ");
return -1; return -1;
} }
...@@ -216,14 +236,9 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a ...@@ -216,14 +236,9 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
,const char* ha1) { ,const char* ha1) {
size_t size; size_t size;
const char *algo = belle_sip_header_authorization_get_algorithm(authorization); const char *algo = belle_sip_header_authorization_get_algorithm(authorization);
if (!strcmp(algo,"MD5")){ size = belle_sip_auth_define_size(algo);
size = 33; if(!size) {
} belle_sip_error("Algorithm [%s] is not correct ", algo);
else if(!strcmp(algo,"SHA-256")){
size = 65;
}
else{
belle_sip_error("belle_sip_fill_authorization_header, algorithm is neither MD5 nor SHA-256 ");
return -1; return -1;
} }
......
...@@ -1135,8 +1135,8 @@ static void belle_sip_provider_update_or_create_auth_context(belle_sip_provider ...@@ -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, 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) { 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_header_call_id_t* call_id;
belle_sip_list_t* auth_context_iterator; belle_sip_list_t* auth_context_iterator;
belle_sip_list_t* authenticate_lst; belle_sip_list_t* authenticate_lst;
...@@ -1147,9 +1147,11 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ ...@@ -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; belle_sip_auth_event_t* auth_event;
authorization_context_t* auth_context; authorization_context_t* auth_context;
const char* ha1; const char* ha1;
char computed_ha1[33]; char computed_ha1[65];
int result=0; int result=0;
const char* request_method; const char* request_method;
size_t size;
const char* algo;
/*check params*/ /*check params*/
if (!p || !request) { if (!p || !request) {
belle_sip_error("belle_sip_provider_add_authorization bad parameters"); 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 ...@@ -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_nonce(authorization,auth_context->nonce);
belle_sip_header_authorization_set_qop(authorization,auth_context->qop); 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_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)); belle_sip_header_authorization_set_uri(authorization,(belle_sip_uri_t*)belle_sip_request_get_uri(request));
if (auth_context->qop){ if (auth_context->qop){
++auth_context->nonce_count; ++auth_context->nonce_count;
belle_sip_header_authorization_set_nonce_count(authorization,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) { if (auth_event->ha1) {
ha1=auth_event->ha1; ha1=auth_event->ha1;
} else { } 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; ha1=computed_ha1;
} }
if (belle_sip_auth_helper_fill_authorization(authorization 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 ...@@ -1291,6 +1304,11 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ
return result; 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) { void belle_sip_provider_set_recv_error(belle_sip_provider_t *prov, int recv_error) {
belle_sip_list_t *lps; belle_sip_list_t *lps;
belle_sip_list_t *channels; belle_sip_list_t *channels;
......
...@@ -56,6 +56,7 @@ struct belle_sip_refresher { ...@@ -56,6 +56,7 @@ struct belle_sip_refresher {
timer_purpose_t timer_purpose; timer_purpose_t timer_purpose;
unsigned char manual; unsigned char manual;
unsigned int publish_pending; unsigned int publish_pending;
char* algo;
}; };
static void set_or_update_dialog(belle_sip_refresher_t* refresher, belle_sip_dialog_t* dialog); 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); 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 ...@@ -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); belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
} }
} else { } 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){ if (requri){
/*case where we are redirected*/ /*case where we are redirected*/
...@@ -523,7 +524,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher ...@@ -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; break;
} }
case BELLE_SIP_DIALOG_TERMINATED: { case BELLE_SIP_DIALOG_TERMINATED: {
...@@ -816,6 +817,10 @@ const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher ...@@ -816,6 +817,10 @@ const char* belle_sip_refresher_get_realm(const belle_sip_refresher_t* refresher
return refresher->realm; 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) { void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* realm) {
if (refresher->realm){ if (refresher->realm){
belle_sip_free(refresher->realm); belle_sip_free(refresher->realm);
...@@ -826,6 +831,16 @@ void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* ...@@ -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) { const belle_sip_client_transaction_t* belle_sip_refresher_get_transaction(const belle_sip_refresher_t* refresher) {
return refresher->transaction; return refresher->transaction;
} }
......
...@@ -663,7 +663,7 @@ belle_sip_refresher_t* belle_sip_client_transaction_create_refresher(belle_sip_c ...@@ -663,7 +663,7 @@ belle_sip_refresher_t* belle_sip_client_transaction_create_refresher(belle_sip_c
return belle_sip_refresher_new(t); 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* 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_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); 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 ...@@ -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); belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
/*put auth header*/ /*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; 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 rfc 3265
3.3.4. Dialog creation and termination 3.3.4. Dialog creation and termination
......
...@@ -22,13 +22,16 @@ ...@@ -22,13 +22,16 @@
#ifndef _MSC_VER #ifndef _MSC_VER
#include <sys/time.h> #include <sys/time.h>
#include "belle-sip/headers.h"
#include "belle-sip/parameters.h"
#include <stdlib.h>
#endif #endif
#define USERNAME "toto" #define USERNAME "toto"
#define SIPDOMAIN "sip.linphone.org" #define SIPDOMAIN "sip.linphone.org"
#define PASSWD "secret" #define PASSWD "secret"
#define ALGOM "MD5"
static char publish_body[]= static char publish_body[]=
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
...@@ -83,6 +86,7 @@ typedef struct endpoint { ...@@ -83,6 +86,7 @@ typedef struct endpoint {
const char* realm; const char* realm;
unsigned int max_nc_count; unsigned int max_nc_count;
bool_t bad_next_nonce; bool_t bad_next_nonce;
const char* algo;
} endpoint_t; } endpoint_t;
...@@ -112,11 +116,13 @@ static void compute_response(const char* username ...@@ -112,11 +116,13 @@ static void compute_response(const char* username
,const char* nonce ,const char* nonce
,const char* method ,const char* method
,const char* uri ,const char* uri
,char response[33] ) { ,char* response
char ha1[33],ha2[33]; ,size_t size
belle_sip_auth_helper_compute_ha1(username,realm,passwd,ha1); ,const char* algo) {
belle_sip_auth_helper_compute_ha2(method,uri,ha2); char ha1[size],ha2[size];
belle_sip_auth_helper_compute_response(ha1,nonce,ha2,response); 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 static void compute_response_auth_qop(const char* username
...@@ -128,11 +134,13 @@ 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* qop
,const char* method ,const char* method
,const char* uri ,const char* uri
,char response[33] ) { ,char* response
char ha1[33],ha2[33]; ,size_t size
belle_sip_auth_helper_compute_ha1(username,realm,passwd,ha1); ,const char* algo) {
belle_sip_auth_helper_compute_ha2(method,uri,ha2); char ha1[size],ha2[size];
belle_sip_auth_helper_compute_response_qop_auth(ha1, nonce,nonce_count, cnonce,qop,ha2,response); 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 #define MAX_NC_COUNT 5
...@@ -146,16 +154,33 @@ static void server_process_request_event(void *obj, const belle_sip_request_even ...@@ -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_expires_t* expires;
belle_sip_header_authorization_t* authorization; belle_sip_header_authorization_t* authorization;
belle_sip_header_via_t* via; belle_sip_header_via_t* via;
const char* raw_authenticate_digest = "WWW-Authenticate: Digest " const char* raw_authenticate_digest;
"algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; const char* raw_proxy_authenticate_digest;
const char* raw_proxy_authenticate_digest = "Proxy-Authenticate: Digest " if((!strcmp(endpoint->algo,"MD5"))||(!strcmp(endpoint->algo,"MD_SHA"))){
"algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; 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* www_authenticate=NULL;
belle_sip_header_www_authenticate_t* two_www_authenticate=NULL;
const char* auth_uri; const char* auth_uri;
const char* qop; const char* qop;
unsigned char auth_ok=0; 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))); 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 ...@@ -176,7 +201,13 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
} else { } else {
BC_ASSERT_TRUE(BELLE_SIP_OBJECT_IS_INSTANCE_OF(authorization, belle_sip_header_proxy_authorization_t)); 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) { if (qop && strcmp(qop,"auth")==0) {
compute_response_auth_qop( belle_sip_header_authorization_get_username(authorization) compute_response_auth_qop( belle_sip_header_authorization_get_username(authorization)
,belle_sip_header_authorization_get_realm(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 ...@@ -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_header_authorization_get_qop(authorization)
,belle_sip_request_get_method(req) ,belle_sip_request_get_method(req)
,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization))
,local_resp); ,local_resp
,size
,algo);
} else { } else {
/*digest*/ /*digest*/
compute_response(belle_sip_header_authorization_get_username(authorization) 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 ...@@ -196,7 +229,9 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
,endpoint->nonce ,endpoint->nonce
,belle_sip_request_get_method(req) ,belle_sip_request_get_method(req)
,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,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); belle_sip_free((void*)auth_uri);
...@@ -285,8 +320,14 @@ static void server_process_request_event(void *obj, const belle_sip_request_even ...@@ -285,8 +320,14 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
response_code = 407; response_code = 407;
} }
resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),response_code); resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),response_code);
if (www_authenticate) if (www_authenticate){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(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) { if (endpoint->received) {
via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t); 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 ...@@ -430,8 +471,8 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client
uint64_t begin; uint64_t begin;
uint64_t end; uint64_t end;
if (client->expire_in_contact) belle_sip_header_contact_set_expires(contact,1); 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)); 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) if (client->connection_family==AF_INET6)
belle_sip_uri_set_host(dest_uri,"::1"); belle_sip_uri_set_host(dest_uri,"::1");
...@@ -462,7 +503,7 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client ...@@ -462,7 +503,7 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client
} }
if (client->realm 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); 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 ...@@ -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); client->refresher = refresher = belle_sip_client_transaction_create_refresher(trans);
if (client->realm) if (client->realm)
belle_sip_refresher_set_realm(client->refresher, client->realm); belle_sip_refresher_set_realm(client->refresher, client->realm);
if (client->algo)
belle_sip_refresher_set_algorithm(client->refresher, client->algo);
} else { } else {
if (server->auth == none) { if (server->auth == none) {
BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.twoHundredOk,1,1000)); 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 ...@@ -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)); BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredSeven,1,1000));