summaryrefslogtreecommitdiffstats
path: root/tinySIP/src/authentication/tsip_challenge.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinySIP/src/authentication/tsip_challenge.c')
-rwxr-xr-xtinySIP/src/authentication/tsip_challenge.c636
1 files changed, 318 insertions, 318 deletions
diff --git a/tinySIP/src/authentication/tsip_challenge.c b/tinySIP/src/authentication/tsip_challenge.c
index bfe39ee..023c4bf 100755
--- a/tinySIP/src/authentication/tsip_challenge.c
+++ b/tinySIP/src/authentication/tsip_challenge.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -52,33 +52,32 @@
/** Creates new challenge object. */
tsip_challenge_t* tsip_challenge_create(tsip_stack_t* stack, tsk_bool_t isproxy, const char* scheme, const char* realm, const char* nonce, const char* opaque, const char* algorithm, const char* qop)
{
- return tsk_object_new(tsip_challenge_def_t, stack, isproxy,scheme, realm, nonce, opaque, algorithm, qop);
+ return tsk_object_new(tsip_challenge_def_t, stack, isproxy,scheme, realm, nonce, opaque, algorithm, qop);
}
/** Creates new challenge object (with default values). */
tsip_challenge_t* tsip_challenge_create_null(tsip_stack_t* stack)
{
- return tsip_challenge_create(stack, tsk_false, tsk_null, tsk_null, tsk_null, tsk_null, tsk_null, tsk_null);
+ return tsip_challenge_create(stack, tsk_false, tsk_null, tsk_null, tsk_null, tsk_null, tsk_null, tsk_null);
}
int tsip_challenge_reset_cnonce(tsip_challenge_t *self)
{
- if(self){
- if(self->qop) /* client nonce is only used if qop=auth, auth-int or both */
- {
+ if(self) {
+ if(self->qop) { /* client nonce is only used if qop=auth, auth-int or both */
#if 0
- memcpy(self->cnonce, "ecb1d3f6931803ce7ae68099cb946594", 32);
+ memcpy(self->cnonce, "ecb1d3f6931803ce7ae68099cb946594", 32);
#else
- tsk_istr_t istr;
-
- tsk_strrandom(&istr);
- tsk_md5compute(istr, tsk_strlen(istr), &self->cnonce);
+ tsk_istr_t istr;
+
+ tsk_strrandom(&istr);
+ tsk_md5compute(istr, tsk_strlen(istr), &self->cnonce);
#endif
- self->nc = 1;
- }
- }
- return -1;
+ self->nc = 1;
+ }
+ }
+ return -1;
}
//3GPP TS 35.205/6/7/8/9 and RFC 3310
@@ -87,132 +86,132 @@ int tsip_challenge_get_akares(tsip_challenge_t *self, char const *password, char
#define SQN_XOR_AK() (AUTN + 0)
#define SERVER_DATA() (nonce + AKA_RAND_SIZE + AKA_AUTN_SIZE)
- // § ==> XOR
- // || ==> append
-
- AKA_RES_T akares;
-
- int ret = -1;
- tsk_size_t n;
- char *nonce = tsk_null;
-
- AKA_XXX_DECLARE(RAND);
- AKA_XXX_DECLARE(AK);
- AKA_XXX_DECLARE(AMF);
- AKA_XXX_DECLARE(CK);
- AKA_XXX_DECLARE(IK);
- AKA_XXX_DECLARE(K);
- AKA_XXX_DECLARE(SQN);
- AKA_XXX_DECLARE(MAC_A);
- AKA_XXX_DECLARE(AUTN);
-
- AKA_XXX_BZERO(RAND);
- AKA_XXX_BZERO(AK);
- AKA_XXX_BZERO(AMF);
- AKA_XXX_BZERO(CK);
- AKA_XXX_BZERO(IK);
- AKA_XXX_BZERO(K);
- AKA_XXX_BZERO(SQN);
- AKA_XXX_BZERO(MAC_A);
- AKA_XXX_BZERO(AUTN);
-
- /* RFC 3310 subclause 3.2: nonce = base64(RAND || AUTN || SERV_DATA) */
- n = tsk_base64_decode((const uint8_t*)self->nonce, tsk_strlen(self->nonce), &nonce);
- if(n > TSK_MD5_STRING_SIZE){
- TSK_DEBUG_ERROR("The IMS CORE returned an invalid nonce.");
- goto bail;
- }
- if(n < AKA_RAND_SIZE + AKA_AUTN_SIZE){
- TSK_DEBUG_ERROR("The nonce returned by the IMS CORE is too short to contain both [RAND] and [AUTHN]");
- goto bail;
- }
- else{
- /* Get RAND and AUTN */
- memcpy(RAND, nonce, AKA_RAND_SIZE);
- memcpy(AUTN, (nonce + AKA_RAND_SIZE), AKA_AUTN_SIZE);
- }
-
- /* Secret key */
- memcpy(K, password, (tsk_strlen(password) > AKA_K_SIZE ? AKA_K_SIZE : tsk_strlen(password)));
-
- /* 3GPP TS 35.205: AUTN = SQN[§AK] || AMF || MAC-A */
- memcpy(AMF, (AUTN + AKA_SQN_SIZE), AKA_AMF_SIZE);
- memcpy(MAC_A, (AUTN + AKA_SQN_SIZE + AKA_AMF_SIZE), AKA_MAC_A_SIZE);
-
- /* compute OP */
- ComputeOP(TSIP_CHALLENGE_STACK(self)->security.operator_id);
-
- /* Checks that we hold the same AMF */
- for(n=0; n<AKA_AMF_SIZE; n++){
- if(AMF[n] != TSIP_CHALLENGE_STACK(self)->security.amf[n]){
- TSK_DEBUG_ERROR("IMS-AKA error: AMF <> XAMF");
- goto bail;
- }
- }
-
- /* Calculate CK, IK and AK */
- f2345(K, RAND, akares, CK, IK, AK);
-
- /* Calculate SQN from SQN_XOR_AK */
- for(n=0; n<AKA_SQN_SIZE; n++){
- SQN[n] = (uint8_t) (SQN_XOR_AK()[n] ^ AK[n]);
- }
-
- /* Calculate XMAC_A */
- {
- AKA_MAC_A_T XMAC_A;
- memset(XMAC_A, '\0', sizeof(XMAC_A));
-
- f1(K, RAND, SQN, AMF, XMAC_A);
- if(!tsk_strnequals(MAC_A, XMAC_A, AKA_MAC_A_SIZE)){
- TSK_DEBUG_ERROR("IMS-AKA error: XMAC_A [%s] <> MAC_A[%s]", XMAC_A, MAC_A);
- goto bail;
- }
- }
-
- /* RFC 4169 subclause 3
- The HTTP Digest password is derived from base64 encoded PRF(RES || IK||CK, "http-digest-akav2-password")
- or
- PRF(XRES||IK||CK, "http-digest-akav2-password") instead of (RES) or (XRES) respectively.
- Where PRF ==> HMAC_MD5 function.
- */
- if(TSIP_CHALLENGE_IS_AKAv2(self)){
- uint8_t res_ik_ck[AKA_RES_SIZE + AKA_IK_SIZE + AKA_CK_SIZE];
- tsk_md5digest_t md5_digest;
-
- memcpy(res_ik_ck, akares, AKA_RES_SIZE);
- memcpy((res_ik_ck + AKA_RES_SIZE), IK, AKA_IK_SIZE);
- memcpy((res_ik_ck + AKA_RES_SIZE + AKA_IK_SIZE), CK, AKA_CK_SIZE);
-
- if((ret = hmac_md5digest_compute((const uint8_t*)"http-digest-akav2-password", 26, (const char*)res_ik_ck, sizeof(res_ik_ck), md5_digest))){/* PRF(RES||IK||CK, ...) */
- TSK_DEBUG_ERROR("hmac_md5digest_compute() failed. AKAv2 response will be invalid.");
-
- ret = -3;
- goto bail;
- }
- else{/* b64(PRF(...)) */
- if(!tsk_base64_encode(md5_digest, sizeof(md5_digest), result)){
- TSK_DEBUG_ERROR("tsk_base64_encode() failed. AKAv2 response will be invalid.");
-
- ret = -4;
- goto bail;
- }
- }
- }
- else{
- *result = tsk_calloc(1, AKA_RES_SIZE + 1);
- memcpy(*result, akares, AKA_RES_SIZE);
-
- ret = 0;
- }
-
- /* Copy CK and IK */
- memcpy(self->ck, CK, AKA_CK_SIZE);
- memcpy(self->ik, IK, AKA_IK_SIZE);
+ // § ==> XOR
+ // || ==> append
+
+ AKA_RES_T akares;
+
+ int ret = -1;
+ tsk_size_t n;
+ char *nonce = tsk_null;
+
+ AKA_XXX_DECLARE(RAND);
+ AKA_XXX_DECLARE(AK);
+ AKA_XXX_DECLARE(AMF);
+ AKA_XXX_DECLARE(CK);
+ AKA_XXX_DECLARE(IK);
+ AKA_XXX_DECLARE(K);
+ AKA_XXX_DECLARE(SQN);
+ AKA_XXX_DECLARE(MAC_A);
+ AKA_XXX_DECLARE(AUTN);
+
+ AKA_XXX_BZERO(RAND);
+ AKA_XXX_BZERO(AK);
+ AKA_XXX_BZERO(AMF);
+ AKA_XXX_BZERO(CK);
+ AKA_XXX_BZERO(IK);
+ AKA_XXX_BZERO(K);
+ AKA_XXX_BZERO(SQN);
+ AKA_XXX_BZERO(MAC_A);
+ AKA_XXX_BZERO(AUTN);
+
+ /* RFC 3310 subclause 3.2: nonce = base64(RAND || AUTN || SERV_DATA) */
+ n = tsk_base64_decode((const uint8_t*)self->nonce, tsk_strlen(self->nonce), &nonce);
+ if(n > TSK_MD5_STRING_SIZE) {
+ TSK_DEBUG_ERROR("The IMS CORE returned an invalid nonce.");
+ goto bail;
+ }
+ if(n < AKA_RAND_SIZE + AKA_AUTN_SIZE) {
+ TSK_DEBUG_ERROR("The nonce returned by the IMS CORE is too short to contain both [RAND] and [AUTHN]");
+ goto bail;
+ }
+ else {
+ /* Get RAND and AUTN */
+ memcpy(RAND, nonce, AKA_RAND_SIZE);
+ memcpy(AUTN, (nonce + AKA_RAND_SIZE), AKA_AUTN_SIZE);
+ }
+
+ /* Secret key */
+ memcpy(K, password, (tsk_strlen(password) > AKA_K_SIZE ? AKA_K_SIZE : tsk_strlen(password)));
+
+ /* 3GPP TS 35.205: AUTN = SQN[§AK] || AMF || MAC-A */
+ memcpy(AMF, (AUTN + AKA_SQN_SIZE), AKA_AMF_SIZE);
+ memcpy(MAC_A, (AUTN + AKA_SQN_SIZE + AKA_AMF_SIZE), AKA_MAC_A_SIZE);
+
+ /* compute OP */
+ ComputeOP(TSIP_CHALLENGE_STACK(self)->security.operator_id);
+
+ /* Checks that we hold the same AMF */
+ for(n=0; n<AKA_AMF_SIZE; n++) {
+ if(AMF[n] != TSIP_CHALLENGE_STACK(self)->security.amf[n]) {
+ TSK_DEBUG_ERROR("IMS-AKA error: AMF <> XAMF");
+ goto bail;
+ }
+ }
+
+ /* Calculate CK, IK and AK */
+ f2345(K, RAND, akares, CK, IK, AK);
+
+ /* Calculate SQN from SQN_XOR_AK */
+ for(n=0; n<AKA_SQN_SIZE; n++) {
+ SQN[n] = (uint8_t) (SQN_XOR_AK()[n] ^ AK[n]);
+ }
+
+ /* Calculate XMAC_A */
+ {
+ AKA_MAC_A_T XMAC_A;
+ memset(XMAC_A, '\0', sizeof(XMAC_A));
+
+ f1(K, RAND, SQN, AMF, XMAC_A);
+ if(!tsk_strnequals(MAC_A, XMAC_A, AKA_MAC_A_SIZE)) {
+ TSK_DEBUG_ERROR("IMS-AKA error: XMAC_A [%s] <> MAC_A[%s]", XMAC_A, MAC_A);
+ goto bail;
+ }
+ }
+
+ /* RFC 4169 subclause 3
+ The HTTP Digest password is derived from base64 encoded PRF(RES || IK||CK, "http-digest-akav2-password")
+ or
+ PRF(XRES||IK||CK, "http-digest-akav2-password") instead of (RES) or (XRES) respectively.
+ Where PRF ==> HMAC_MD5 function.
+ */
+ if(TSIP_CHALLENGE_IS_AKAv2(self)) {
+ uint8_t res_ik_ck[AKA_RES_SIZE + AKA_IK_SIZE + AKA_CK_SIZE];
+ tsk_md5digest_t md5_digest;
+
+ memcpy(res_ik_ck, akares, AKA_RES_SIZE);
+ memcpy((res_ik_ck + AKA_RES_SIZE), IK, AKA_IK_SIZE);
+ memcpy((res_ik_ck + AKA_RES_SIZE + AKA_IK_SIZE), CK, AKA_CK_SIZE);
+
+ if((ret = hmac_md5digest_compute((const uint8_t*)"http-digest-akav2-password", 26, (const char*)res_ik_ck, sizeof(res_ik_ck), md5_digest))) { /* PRF(RES||IK||CK, ...) */
+ TSK_DEBUG_ERROR("hmac_md5digest_compute() failed. AKAv2 response will be invalid.");
+
+ ret = -3;
+ goto bail;
+ }
+ else { /* b64(PRF(...)) */
+ if(!tsk_base64_encode(md5_digest, sizeof(md5_digest), result)) {
+ TSK_DEBUG_ERROR("tsk_base64_encode() failed. AKAv2 response will be invalid.");
+
+ ret = -4;
+ goto bail;
+ }
+ }
+ }
+ else {
+ *result = tsk_calloc(1, AKA_RES_SIZE + 1);
+ memcpy(*result, akares, AKA_RES_SIZE);
+
+ ret = 0;
+ }
+
+ /* Copy CK and IK */
+ memcpy(self->ck, CK, AKA_CK_SIZE);
+ memcpy(self->ik, IK, AKA_IK_SIZE);
bail:
- TSK_FREE(nonce);
- return ret;
+ TSK_FREE(nonce);
+ return ret;
#undef SQN_XOR_AK
#undef SERVER_DATA
@@ -220,124 +219,124 @@ bail:
int tsip_challenge_get_response(tsip_challenge_t *self, const char* method, const char* uristring, const tsk_buffer_t* entity_body, tsk_md5string_t* response)
{
- if(TSIP_CHALLENGE_IS_DIGEST(self) && self->stack){
- tsk_md5string_t ha1, ha2;
- nonce_count_t nc;
-
- /* ===
- Calculate HA1 = MD5(A1) = M5(username:realm:secret)
- In case of AKAv1-MD5 and AKAv2-MD5 the secret must be computed as per RFC 3310 + 3GPP TS 206/7/8/9.
- The resulting AKA RES parameter is treated as a "password"/"secret" when calculating the response directive of RFC 2617.
- */
- if(TSIP_CHALLENGE_IS_AKAv1(self) || TSIP_CHALLENGE_IS_AKAv2(self)){
- char* akaresult = tsk_null;
- tsip_challenge_get_akares(self, TSIP_CHALLENGE_STACK(self)->identity.password, &akaresult);
- if(thttp_auth_digest_HA1(TSIP_CHALLENGE_USERNAME(self), self->realm, akaresult, &ha1)){
- // return -1;
- }
- TSK_FREE(akaresult);
- }
- else{
- if(!tsk_strnullORempty(self->ha1_hexstr)){
- // use HA1 provide be the user (e.g. webrtc2sip server will need this to authenticate INVITEs when acting as b2bua)
- memset(ha1, 0, sizeof(tsk_md5string_t));
- memcpy(ha1, self->ha1_hexstr, (TSK_MD5_DIGEST_SIZE << 1));
- }
- else{
- thttp_auth_digest_HA1(TSIP_CHALLENGE_USERNAME(self), self->realm, TSIP_CHALLENGE_STACK(self)->identity.password, &ha1);
- }
- }
-
- /* ===
- HA2
- */
- thttp_auth_digest_HA2(method,
- uristring,
- entity_body,
- self->qop,
- &ha2);
-
- /* RESPONSE */
- if(self->nc){
- THTTP_NCOUNT_2_STRING(self->nc, nc);
- }
- thttp_auth_digest_response((const tsk_md5string_t *)&ha1,
- self->nonce,
- nc,
- self->cnonce,
- self->qop,
- (const tsk_md5string_t *)&ha2,
- response);
-
- if(self->qop){
- self->nc++;
- }
-
- return 0;
- }
- return -1;
+ if(TSIP_CHALLENGE_IS_DIGEST(self) && self->stack) {
+ tsk_md5string_t ha1, ha2;
+ nonce_count_t nc;
+
+ /* ===
+ Calculate HA1 = MD5(A1) = M5(username:realm:secret)
+ In case of AKAv1-MD5 and AKAv2-MD5 the secret must be computed as per RFC 3310 + 3GPP TS 206/7/8/9.
+ The resulting AKA RES parameter is treated as a "password"/"secret" when calculating the response directive of RFC 2617.
+ */
+ if(TSIP_CHALLENGE_IS_AKAv1(self) || TSIP_CHALLENGE_IS_AKAv2(self)) {
+ char* akaresult = tsk_null;
+ tsip_challenge_get_akares(self, TSIP_CHALLENGE_STACK(self)->identity.password, &akaresult);
+ if(thttp_auth_digest_HA1(TSIP_CHALLENGE_USERNAME(self), self->realm, akaresult, &ha1)) {
+ // return -1;
+ }
+ TSK_FREE(akaresult);
+ }
+ else {
+ if(!tsk_strnullORempty(self->ha1_hexstr)) {
+ // use HA1 provide be the user (e.g. webrtc2sip server will need this to authenticate INVITEs when acting as b2bua)
+ memset(ha1, 0, sizeof(tsk_md5string_t));
+ memcpy(ha1, self->ha1_hexstr, (TSK_MD5_DIGEST_SIZE << 1));
+ }
+ else {
+ thttp_auth_digest_HA1(TSIP_CHALLENGE_USERNAME(self), self->realm, TSIP_CHALLENGE_STACK(self)->identity.password, &ha1);
+ }
+ }
+
+ /* ===
+ HA2
+ */
+ thttp_auth_digest_HA2(method,
+ uristring,
+ entity_body,
+ self->qop,
+ &ha2);
+
+ /* RESPONSE */
+ if(self->nc) {
+ THTTP_NCOUNT_2_STRING(self->nc, nc);
+ }
+ thttp_auth_digest_response((const tsk_md5string_t *)&ha1,
+ self->nonce,
+ nc,
+ self->cnonce,
+ self->qop,
+ (const tsk_md5string_t *)&ha2,
+ response);
+
+ if(self->qop) {
+ self->nc++;
+ }
+
+ return 0;
+ }
+ return -1;
}
int tsip_challenge_update(tsip_challenge_t *self, const char* scheme, const char* realm, const char* nonce, const char* opaque, const char* algorithm, const char* qop)
{
- if(self){
- int noncechanged = !tsk_striequals(self->nonce, nonce);
-
- tsk_strupdate(&self->scheme, scheme);
- tsk_strupdate(&self->realm, realm);
- tsk_strupdate(&self->nonce, nonce);
- tsk_strupdate(&self->opaque, opaque);
- tsk_strupdate(&self->algorithm, algorithm);
- if(qop){
- self->qop = tsk_strcontains(qop, tsk_strlen(qop), "auth-int") ? "auth-int" :
- (tsk_strcontains(qop, tsk_strlen(qop), "auth") ? "auth" : tsk_null);
- }
-
- if(noncechanged && self->qop){
- tsip_challenge_reset_cnonce(self);
- }
- return 0;
- }
- return -1;
+ if(self) {
+ int noncechanged = !tsk_striequals(self->nonce, nonce);
+
+ tsk_strupdate(&self->scheme, scheme);
+ tsk_strupdate(&self->realm, realm);
+ tsk_strupdate(&self->nonce, nonce);
+ tsk_strupdate(&self->opaque, opaque);
+ tsk_strupdate(&self->algorithm, algorithm);
+ if(qop) {
+ self->qop = tsk_strcontains(qop, tsk_strlen(qop), "auth-int") ? "auth-int" :
+ (tsk_strcontains(qop, tsk_strlen(qop), "auth") ? "auth" : tsk_null);
+ }
+
+ if(noncechanged && self->qop) {
+ tsip_challenge_reset_cnonce(self);
+ }
+ return 0;
+ }
+ return -1;
}
int tsip_challenge_set_cred(tsip_challenge_t *self, const char* username, const char* ha1_hexstr)
{
- if(!self || tsk_strlen(ha1_hexstr) != (TSK_MD5_DIGEST_SIZE << 1)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_strupdate(&self->username, username);
- tsk_strupdate(&self->ha1_hexstr, ha1_hexstr);
- return 0;
+ if(!self || tsk_strlen(ha1_hexstr) != (TSK_MD5_DIGEST_SIZE << 1)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_strupdate(&self->username, username);
+ tsk_strupdate(&self->ha1_hexstr, ha1_hexstr);
+ return 0;
}
tsip_header_t *tsip_challenge_create_header_authorization(tsip_challenge_t *self, const tsip_request_t *request)
{
- tsk_md5string_t response;
- nonce_count_t nc;
- char *uristring = tsk_null;
- tsip_header_t *header = tsk_null;
-
- if(!self || !self->stack || !request){
- goto bail;
- }
-
- if(!(uristring = tsip_uri_tostring(request->line.request.uri, tsk_true, tsk_false))){
- TSK_DEBUG_ERROR("Failed to parse URI: %s", uristring);
- goto bail;
- }
-
- /* We compute the nc here because @ref tsip_challenge_get_response function will increment it's value. */
- if(self->nc){
- THTTP_NCOUNT_2_STRING(self->nc, nc);
- }
-
- /* entity_body ==> request-content */
- if(tsip_challenge_get_response(self, request->line.request.method, uristring, request->Content, &response)){
- goto bail;
- }
-
+ tsk_md5string_t response;
+ nonce_count_t nc;
+ char *uristring = tsk_null;
+ tsip_header_t *header = tsk_null;
+
+ if(!self || !self->stack || !request) {
+ goto bail;
+ }
+
+ if(!(uristring = tsip_uri_tostring(request->line.request.uri, tsk_true, tsk_false))) {
+ TSK_DEBUG_ERROR("Failed to parse URI: %s", uristring);
+ goto bail;
+ }
+
+ /* We compute the nc here because @ref tsip_challenge_get_response function will increment it's value. */
+ if(self->nc) {
+ THTTP_NCOUNT_2_STRING(self->nc, nc);
+ }
+
+ /* entity_body ==> request-content */
+ if(tsip_challenge_get_response(self, request->line.request.method, uristring, request->Content, &response)) {
+ goto bail;
+ }
+
#define TSIP_AUTH_COPY_VALUES(hdr) \
hdr->username = tsk_strdup(TSIP_CHALLENGE_USERNAME(self)); \
@@ -351,40 +350,40 @@ tsip_header_t *tsip_challenge_create_header_authorization(tsip_challenge_t *self
hdr->uri = tsk_strdup(uristring); \
hdr->nc = self->nc? tsk_strdup(nc) : 0; \
hdr->response = tsk_strdup(response); \
-
- if(self->isproxy){
- tsip_header_Proxy_Authorization_t *proxy_auth = tsip_header_Proxy_Authorization_create();
- TSIP_AUTH_COPY_VALUES(proxy_auth);
- header = TSIP_HEADER(proxy_auth);
- }
- else{
- tsip_header_Authorization_t *auth = tsip_header_Authorization_create();
- TSIP_AUTH_COPY_VALUES(auth);
- header = TSIP_HEADER(auth);
- }
+
+ if(self->isproxy) {
+ tsip_header_Proxy_Authorization_t *proxy_auth = tsip_header_Proxy_Authorization_create();
+ TSIP_AUTH_COPY_VALUES(proxy_auth);
+ header = TSIP_HEADER(proxy_auth);
+ }
+ else {
+ tsip_header_Authorization_t *auth = tsip_header_Authorization_create();
+ TSIP_AUTH_COPY_VALUES(auth);
+ header = TSIP_HEADER(auth);
+ }
bail:
- TSK_FREE(uristring);
+ TSK_FREE(uristring);
- return header;
+ return header;
#undef TSIP_AUTH_COPY_VALUES
}
tsip_header_t *tsip_challenge_create_empty_header_authorization(const char* username, const char* realm, const char* uristring)
{
- tsip_header_Authorization_t *header = tsip_header_Authorization_create();
-
- if(header){
- header->scheme = tsk_strdup("Digest");
- header->username = tsk_strdup(username);
- header->realm = tsk_strdup(realm);
- header->nonce = tsk_strdup("");
- header->response = tsk_strdup("");
- header->uri = tsk_strdup(uristring);
- }
-
- return TSIP_HEADER(header);
+ tsip_header_Authorization_t *header = tsip_header_Authorization_create();
+
+ if(header) {
+ header->scheme = tsk_strdup("Digest");
+ header->username = tsk_strdup(username);
+ header->realm = tsk_strdup(realm);
+ header->nonce = tsk_strdup("");
+ header->response = tsk_strdup("");
+ header->uri = tsk_strdup(uristring);
+ }
+
+ return TSIP_HEADER(header);
}
@@ -419,59 +418,60 @@ tsip_header_t *tsip_challenge_create_empty_header_authorization(const char* user
*/
static tsk_object_t* tsip_challenge_ctor(tsk_object_t *self, va_list * app)
{
- tsip_challenge_t *challenge = self;
- if(challenge){
- const char* qop;
-
- challenge->stack = va_arg(*app, const tsip_stack_handle_t *);
- challenge->isproxy = va_arg(*app, tsk_bool_t);
- challenge->username = tsk_strdup(((const struct tsip_stack_s*)challenge->stack)->identity.impi);
- challenge->scheme = tsk_strdup(va_arg(*app, const char*));
- challenge->realm = tsk_strdup(va_arg(*app, const char*));
- challenge->nonce = tsk_strdup(va_arg(*app, const char*));
- challenge->opaque = tsk_strdup(va_arg(*app, const char*));
- challenge->algorithm = tsk_strdup(va_arg(*app, const char*));
- qop = va_arg(*app, const char*);
- if(qop){
- challenge->qop = tsk_strcontains(qop, tsk_strlen(qop), "auth-int") ? "auth-int" :
- (tsk_strcontains(qop, tsk_strlen(qop), "auth") ? "auth" : tsk_null);
- }
-
- if(challenge->qop){
- tsip_challenge_reset_cnonce(challenge);
- }
- }
- else TSK_DEBUG_ERROR("Failed to create new sip challenge object.");
-
- return self;
+ tsip_challenge_t *challenge = self;
+ if(challenge) {
+ const char* qop;
+
+ challenge->stack = va_arg(*app, const tsip_stack_handle_t *);
+ challenge->isproxy = va_arg(*app, tsk_bool_t);
+ challenge->username = tsk_strdup(((const struct tsip_stack_s*)challenge->stack)->identity.impi);
+ challenge->scheme = tsk_strdup(va_arg(*app, const char*));
+ challenge->realm = tsk_strdup(va_arg(*app, const char*));
+ challenge->nonce = tsk_strdup(va_arg(*app, const char*));
+ challenge->opaque = tsk_strdup(va_arg(*app, const char*));
+ challenge->algorithm = tsk_strdup(va_arg(*app, const char*));
+ qop = va_arg(*app, const char*);
+ if(qop) {
+ challenge->qop = tsk_strcontains(qop, tsk_strlen(qop), "auth-int") ? "auth-int" :
+ (tsk_strcontains(qop, tsk_strlen(qop), "auth") ? "auth" : tsk_null);
+ }
+
+ if(challenge->qop) {
+ tsip_challenge_reset_cnonce(challenge);
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create new sip challenge object.");
+ }
+
+ return self;
}
/**@ingroup tsip_challenge_group
*/
static tsk_object_t* tsip_challenge_dtor(tsk_object_t *self)
{
- tsip_challenge_t *challenge = self;
- if(challenge){
- TSK_FREE(challenge->username);
- TSK_FREE(challenge->scheme);
- TSK_FREE(challenge->realm);
- TSK_FREE(challenge->nonce);
- TSK_FREE(challenge->opaque);
- TSK_FREE(challenge->algorithm);
- TSK_FREE(challenge->ha1_hexstr);
- }
- else{
- TSK_DEBUG_ERROR("Null SIP challenge object.");
- }
-
- return self;
+ tsip_challenge_t *challenge = self;
+ if(challenge) {
+ TSK_FREE(challenge->username);
+ TSK_FREE(challenge->scheme);
+ TSK_FREE(challenge->realm);
+ TSK_FREE(challenge->nonce);
+ TSK_FREE(challenge->opaque);
+ TSK_FREE(challenge->algorithm);
+ TSK_FREE(challenge->ha1_hexstr);
+ }
+ else {
+ TSK_DEBUG_ERROR("Null SIP challenge object.");
+ }
+
+ return self;
}
-static const tsk_object_def_t tsip_challenge_def_s =
-{
- sizeof(tsip_challenge_t),
- tsip_challenge_ctor,
- tsip_challenge_dtor,
- tsk_null
+static const tsk_object_def_t tsip_challenge_def_s = {
+ sizeof(tsip_challenge_t),
+ tsip_challenge_ctor,
+ tsip_challenge_dtor,
+ tsk_null
};
const tsk_object_def_t *tsip_challenge_def_t = &tsip_challenge_def_s;
OpenPOWER on IntegriCloud