Commit 8a8c3b54 authored by jehan's avatar jehan

implement qop=auth mode

parent 89abc5b1
......@@ -39,6 +39,9 @@ belle_sip_header_proxy_authorization_t* belle_sip_auth_helper_create_proxy_autho
/**
* compute and set response value according to parameters
* HA1=MD5(username:realm:passwd)
* fills cnonce if needed (qop=auth);
* fills qop
*
* @return 0 if succeed
*/
int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* authorization
......
......@@ -332,6 +332,10 @@ belle_sip_header_authorization_t* belle_sip_header_authorization_parse(const cha
const char* belle_sip_header_authorization_get_algorithm(const belle_sip_header_authorization_t* authorization );
const char* belle_sip_header_authorization_get_cnonce(const belle_sip_header_authorization_t* authorization );
const char* belle_sip_header_authorization_get_nonce(const belle_sip_header_authorization_t* authorization);
/*convert nonce count as string id present
* @return 0 in case of success
* */
int belle_sip_header_authorization_get_nonce_count_as_string(const belle_sip_header_authorization_t* authorization,char nounce_count[9]);
int belle_sip_header_authorization_get_nonce_count(const belle_sip_header_authorization_t* authorization);
const char* belle_sip_header_authorization_get_opaque(const belle_sip_header_authorization_t* authorization);
const char* belle_sip_header_authorization_get_qop(const belle_sip_header_authorization_t* authorization);
......
......@@ -81,11 +81,15 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
md5_byte_t out[16];
md5_state_t state;
int auth_mode=0;
char* uri;
char ha2[16*2 + 1];
char response[16*2 + 1];
response[33]=ha2[33]='\0';
int di;
char nonce_count[9];
char cnonce[9];
if (belle_sip_header_authorization_get_scheme(authorization) != NULL &&
strcmp("Digest",belle_sip_header_authorization_get_scheme(authorization))!=0) {
belle_sip_error("belle_sip_fill_authorization_header, unsupported schema [%s]"
......@@ -93,14 +97,21 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
return -1;
}
if (belle_sip_header_authorization_get_qop(authorization)
/*&& strcmp("auth",belle_sip_header_authorization_get_qop(authorization))!=0*/) {
belle_sip_error("belle_sip_fill_authorization_header, unsupported qop [%s], use auth instead"
&& !(auth_mode=strcmp("auth",belle_sip_header_authorization_get_qop(authorization))==0)) {
belle_sip_error("belle_sip_fill_authorization_header, unsupported qop [%s], use auth or nothing instead"
,belle_sip_header_authorization_get_qop(authorization));
return -1;
}
CHECK_IS_PRESENT(authorization,authorization,realm)
CHECK_IS_PRESENT(authorization,authorization,nonce)
CHECK_IS_PRESENT(authorization,authorization,uri)
if (auth_mode) {
CHECK_IS_PRESENT(authorization,authorization,nonce_count)
if (!belle_sip_header_authorization_get_cnonce(authorization)) {
snprintf(cnonce,sizeof(cnonce),"%08x",(short)(long)authorization);
belle_sip_header_authorization_set_cnonce(authorization,cnonce);
}
}
if (!method) {
belle_sip_error("belle_sip_fill_authorization_header, method not found ");
return -1;
......@@ -117,7 +128,8 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
belle_sip_free(uri);
for (di = 0; di < 16; ++di)
sprintf(ha2 + di * 2, "%02x", out[di]);
/*response=MD5(HA1:nonce:HA2)*/
md5_init(&state);
md5_append(&state,(const md5_byte_t *)ha1,strlen(ha1));
md5_append(&state,(const md5_byte_t *)":",1);
......@@ -125,6 +137,23 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
,(const md5_byte_t *)belle_sip_header_authorization_get_nonce(authorization)
,strlen(belle_sip_header_authorization_get_nonce(authorization)));
md5_append(&state,(const md5_byte_t *)":",1);
if (auth_mode) {
/*response=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2)*/
belle_sip_header_authorization_get_nonce_count_as_string(authorization,nonce_count);
md5_append(&state
,(const md5_byte_t *)nonce_count
,sizeof(nonce_count)-1);
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
,(const md5_byte_t *)belle_sip_header_authorization_get_cnonce(authorization)
,strlen(belle_sip_header_authorization_get_cnonce(authorization)));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
,(const md5_byte_t *)belle_sip_header_authorization_get_qop(authorization)
,strlen(belle_sip_header_authorization_get_qop(authorization)));
md5_append(&state,(const md5_byte_t *)":",1);
} /*else response=MD5(HA1:nonce:HA2)*/
md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
md5_finish(&state,out);
/*copy values*/
......
......@@ -856,6 +856,7 @@ void belle_sip_header_authorization_set_uri(belle_sip_header_authorization_t* au
authorization->uri=uri;
}
int belle_sip_header_authorization_marshal(belle_sip_header_authorization_t* authorization, char* buff,unsigned int offset,unsigned int buff_size) {
char nonce_count[10];
AUTH_BASE_MARSHAL(authorization)
if (authorization->username) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%susername=\"%s\"",border,authorization->username);\
......@@ -880,7 +881,8 @@ int belle_sip_header_authorization_marshal(belle_sip_header_authorization_t* aut
border=", ";
}
if (authorization->nonce_count>0) {
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%snc=%08i",border,authorization->nonce_count);
belle_sip_header_authorization_get_nonce_count_as_string(authorization,nonce_count);
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%snc=%s",border,nonce_count);
border=", ";
}
if (authorization->qop) {
......@@ -900,6 +902,16 @@ GET_SET_STRING(belle_sip_header_authorization,cnonce);
GET_SET_STRING(belle_sip_header_authorization,opaque);
GET_SET_STRING(belle_sip_header_authorization,qop);
GET_SET_INT(belle_sip_header_authorization,nonce_count,int)
int belle_sip_header_authorization_get_nonce_count_as_string(const belle_sip_header_authorization_t* authorization,char nounce_count[9]) {
nounce_count[0]='\0';
if (authorization->nonce_count>0) {
snprintf(nounce_count,9,"%08x",authorization->nonce_count);
return 0;
} else {
return -1;
}
}
/**************************
*Proxy-Authorization header object inherent from parameters
****************************
......
......@@ -23,18 +23,37 @@
static void test_authentication(void) {
const char* l_raw_header = "WWW-Authenticate: Digest "
"algorithm=MD5, realm=\"sip.linphone.org\", opaque=\"1bc7f9097684320\","
" qop=\"auth,auth-int\", nonce=\"cz3h0gAAAAC06TKKAABmTz1V9OcAAAAA\"";
" nonce=\"cz3h0gAAAAC06TKKAABmTz1V9OcAAAAA\"";
char ha1[33];
belle_sip_header_www_authenticate_t* www_authenticate=belle_sip_header_www_authenticate_parse(l_raw_header);
belle_sip_header_authorization_t* authorization = belle_sip_auth_helper_create_authorization(www_authenticate);
belle_sip_header_authorization_set_uri(authorization,belle_sip_uri_parse("sip:sip.linphone.org"));
//belle_sip_header_authorization_set_qop(authorization,"auth");
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_compute_ha1("jehan-mac","sip.linphone.org","toto",ha1));
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_fill_authorization(authorization,"REGISTER",ha1));
CU_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_response(authorization),"77ebf3de72e41934d806175586086508");
belle_sip_object_unref(www_authenticate);
belle_sip_object_unref(authorization);
}
static void test_authentication_qop_auth(void) {
const char* l_raw_header = "WWW-Authenticate: Digest "
"algorithm=MD5, realm=\"sip.linphone.org\", opaque=\"1bc7f9097684320\","
" qop=\"auth,auth-int\", nonce=\"cz3h0gAAAAC06TKKAABmTz1V9OcAAAAA\"";
char ha1[33];
belle_sip_header_www_authenticate_t* www_authenticate=belle_sip_header_www_authenticate_parse(l_raw_header);
belle_sip_header_authorization_t* authorization = belle_sip_auth_helper_create_authorization(www_authenticate);
belle_sip_header_authorization_set_uri(authorization,belle_sip_uri_parse("sip:sip.linphone.org"));
belle_sip_header_authorization_set_nonce_count(authorization,1);
belle_sip_header_authorization_set_qop(authorization,"auth");
belle_sip_header_authorization_set_cnonce(authorization,"8302210f"); /*for testing purpose*/
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_compute_ha1("jehan-mac","sip.linphone.org","toto",ha1));
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_fill_authorization(authorization,"REGISTER",ha1));
CU_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_qop(authorization),"auth");
CU_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_response(authorization),"694dab8dfe7d50d28ba61e8c43e30666");
CU_ASSERT_EQUAL(belle_sip_header_authorization_get_nonce_count(authorization),1);
belle_sip_object_unref(www_authenticate);
belle_sip_object_unref(authorization);
}
static void test_proxy_authentication(void) {
const char* l_raw_header = "Proxy-Authenticate: Digest "
"algorithm=MD5, realm=\"sip.linphone.org\", opaque=\"1bc7f9097684320\","
......@@ -43,7 +62,6 @@ static void test_proxy_authentication(void) {
belle_sip_header_proxy_authenticate_t* proxy_authenticate=belle_sip_header_proxy_authenticate_parse(l_raw_header);
belle_sip_header_proxy_authorization_t* proxy_authorization = belle_sip_auth_helper_create_proxy_authorization(proxy_authenticate);
belle_sip_header_authorization_set_uri(BELLE_SIP_HEADER_AUTHORIZATION(proxy_authorization),belle_sip_uri_parse("sip:sip.linphone.org"));
//belle_sip_header_authorization_set_qop(BELLE_SIP_HEADER_AUTHORIZATION(proxy_authorization),"auth");
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_compute_ha1("jehan-mac","sip.linphone.org","toto",ha1));
CU_ASSERT_EQUAL_FATAL(0,belle_sip_auth_helper_fill_proxy_authorization(proxy_authorization,"REGISTER",ha1));
CU_ASSERT_STRING_EQUAL(belle_sip_header_authorization_get_response(BELLE_SIP_HEADER_AUTHORIZATION(proxy_authorization))
......@@ -66,6 +84,9 @@ int belle_sip_authentication_helper_suite () {
if (NULL == CU_add_test(pSuite, "test of simple digest authentication uri", test_authentication)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "auth digest authentication uri", test_authentication_qop_auth)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "test of simple digest proxy authentication", test_proxy_authentication)) {
return CU_get_error();
}
......
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