|
@@ -276,7 +276,6 @@ int challenge(struct sip_msg* msg, char* str1, char* str2, int is_proxy_auth, ch
|
|
|
str private_identity, public_identity, auts = {0, 0}, nonce = {0, 0};
|
|
|
auth_vector *av = 0;
|
|
|
int algo_type;
|
|
|
-
|
|
|
str route_name;
|
|
|
|
|
|
saved_transaction_t* saved_t;
|
|
@@ -346,8 +345,8 @@ int challenge(struct sip_msg* msg, char* str1, char* str2, int is_proxy_auth, ch
|
|
|
|
|
|
algo_type = registration_default_algorithm_type;
|
|
|
|
|
|
- /* check if it is a synchronization request */
|
|
|
- //TODO this is MAR syncing - have removed it currently - TOD maybe put back in
|
|
|
+// /* check if it is a synchronization request */
|
|
|
+// //TODO this is MAR syncing - have removed it currently - TOD maybe put back in
|
|
|
// auts = ims_get_auts(msg, realm, is_proxy_auth);
|
|
|
// if (auts.len) {
|
|
|
// LM_DBG("IMS Auth Synchronization requested <%.*s>\n", auts.len, auts.s);
|
|
@@ -363,19 +362,15 @@ int challenge(struct sip_msg* msg, char* str1, char* str2, int is_proxy_auth, ch
|
|
|
// av = get_auth_vector(private_identity, public_identity, AUTH_VECTOR_SENT, &nonce, &aud_hash);
|
|
|
//
|
|
|
// if (!av) {
|
|
|
-// LM_ERR("Nonce not regonized as sent, no sync!\n");
|
|
|
+// LM_ERR("nonce not recognized as sent, no sync!\n");
|
|
|
// auts.len = 0;
|
|
|
// auts.s = 0;
|
|
|
// } else {
|
|
|
// av->status = AUTH_VECTOR_USELESS;
|
|
|
// auth_data_unlock(aud_hash);
|
|
|
// av = 0;
|
|
|
+// resync = 1;
|
|
|
// }
|
|
|
-//
|
|
|
-// //RICHARD REMOVED REALM - this is diameter realm set in cxdx not SIP domain
|
|
|
-// // if synchronization - force MAR - if MAR ok, old avs will be droped
|
|
|
-// multimedia_auth_request(msg, public_identity, private_identity, av_request_at_sync,
|
|
|
-// auth_scheme_types[algo_type], nonce, auts, scscf_name_str);
|
|
|
// }
|
|
|
|
|
|
//RICHARD changed this
|
|
@@ -446,7 +441,6 @@ int challenge(struct sip_msg* msg, char* str1, char* str2, int is_proxy_auth, ch
|
|
|
memcpy(saved_t->realm.s, realm.s, realm.len);
|
|
|
saved_t->realm.len = realm.len;
|
|
|
|
|
|
-
|
|
|
saved_t->is_proxy_auth = is_proxy_auth;
|
|
|
|
|
|
LM_DBG("Suspending SIP TM transaction\n");
|
|
@@ -474,6 +468,158 @@ int www_challenge(struct sip_msg* msg, char* _route, char* str1, char* str2) {
|
|
|
return challenge(msg, str1, str2, 0, _route);
|
|
|
}
|
|
|
|
|
|
+int www_resync_auth(struct sip_msg* msg, char* _route, char* str1, char* str2) {
|
|
|
+
|
|
|
+ str realm = {0, 0};
|
|
|
+ unsigned int aud_hash;
|
|
|
+ str private_identity, public_identity, auts = {0, 0}, nonce = {0, 0};
|
|
|
+ auth_vector *av = 0;
|
|
|
+ int algo_type;
|
|
|
+ int is_proxy_auth=0;
|
|
|
+ str route_name;
|
|
|
+
|
|
|
+ saved_transaction_t* saved_t;
|
|
|
+ tm_cell_t *t = 0;
|
|
|
+ cfg_action_t* cfg_action;
|
|
|
+
|
|
|
+ if (fixup_get_svalue(msg, (gparam_t*) _route, &route_name) != 0) {
|
|
|
+ LM_ERR("no async route block for assign_server_unreg\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
|
|
|
+ int ri = route_get(&main_rt, route_name.s);
|
|
|
+ if (ri < 0) {
|
|
|
+ LM_ERR("unable to find route block [%.*s]\n", route_name.len, route_name.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ cfg_action = main_rt.rlist[ri];
|
|
|
+ if (cfg_action == NULL) {
|
|
|
+ LM_ERR("empty action lists in route block [%.*s]\n", route_name.len, route_name.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (get_str_fparam(&realm, msg, (fparam_t*) str1) < 0) {
|
|
|
+ LM_ERR("failed to get realm value\n");
|
|
|
+ return CSCF_RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (realm.len == 0) {
|
|
|
+ LM_ERR("invalid realm value - empty content\n");
|
|
|
+ return CSCF_RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ create_return_code(CSCF_RETURN_ERROR);
|
|
|
+
|
|
|
+ if (msg->first_line.type != SIP_REQUEST) {
|
|
|
+ LM_ERR("This message is not a request\n");
|
|
|
+ return CSCF_RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* get the private_identity */
|
|
|
+ private_identity = get_private_identity(msg, realm, is_proxy_auth);
|
|
|
+ if (!private_identity.len) {
|
|
|
+ LM_ERR("No private identity specified (Authorization: username)\n");
|
|
|
+ stateful_request_reply(msg, 403, MSG_403_NO_PRIVATE);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+ /* get the public_identity */
|
|
|
+ public_identity = get_public_identity(msg);
|
|
|
+ if (!public_identity.len) {
|
|
|
+ LM_ERR("No public identity specified (To:)\n");
|
|
|
+ stateful_request_reply(msg, 403, MSG_403_NO_PUBLIC);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+
|
|
|
+ algo_type = registration_default_algorithm_type;
|
|
|
+
|
|
|
+ /* check if it is a synchronization request */
|
|
|
+ //TODO this is MAR syncing - have removed it currently - TOD maybe put back in
|
|
|
+ auts = ims_get_auts(msg, realm, is_proxy_auth);
|
|
|
+ if (auts.len) {
|
|
|
+ LM_DBG("IMS Auth Synchronization requested <%.*s>\n", auts.len, auts.s);
|
|
|
+
|
|
|
+ nonce = ims_get_nonce(msg, realm);
|
|
|
+ if (nonce.len == 0) {
|
|
|
+ LM_DBG("Nonce not found (Authorization: nonce)\n");
|
|
|
+ stateful_request_reply(msg, 403, MSG_403_NO_NONCE);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+ av = get_auth_vector(private_identity, public_identity, AUTH_VECTOR_USED, &nonce, &aud_hash);
|
|
|
+ if (!av)
|
|
|
+ av = get_auth_vector(private_identity, public_identity, AUTH_VECTOR_SENT, &nonce, &aud_hash);
|
|
|
+
|
|
|
+ if (!av) {
|
|
|
+ LM_ERR("nonce not recognized as sent, no sync!\n");
|
|
|
+ auts.len = 0;
|
|
|
+ auts.s = 0;
|
|
|
+ } else {
|
|
|
+ av->status = AUTH_VECTOR_USELESS;
|
|
|
+ auth_data_unlock(aud_hash);
|
|
|
+ av = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //before we send lets suspend the transaction
|
|
|
+ t = tmb.t_gett();
|
|
|
+ if (t == NULL || t == T_UNDEFINED) {
|
|
|
+ if (tmb.t_newtran(msg) < 0) {
|
|
|
+ LM_ERR("cannot create the transaction for MAR async\n");
|
|
|
+ stateful_request_reply(msg, 480, MSG_480_DIAMETER_ERROR);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+ t = tmb.t_gett();
|
|
|
+ if (t == NULL || t == T_UNDEFINED) {
|
|
|
+ LM_ERR("cannot lookup the transaction\n");
|
|
|
+ stateful_request_reply(msg, 480, MSG_480_DIAMETER_ERROR);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ saved_t = shm_malloc(sizeof(saved_transaction_t));
|
|
|
+ if (!saved_t) {
|
|
|
+ LM_ERR("no more memory trying to save transaction state\n");
|
|
|
+ return CSCF_RETURN_ERROR;
|
|
|
+
|
|
|
+ }
|
|
|
+ memset(saved_t, 0, sizeof(saved_transaction_t));
|
|
|
+ saved_t->act = cfg_action;
|
|
|
+
|
|
|
+ saved_t->realm.s = (char*) shm_malloc(realm.len + 1);
|
|
|
+ if (!saved_t->realm.s) {
|
|
|
+ LM_ERR("no more memory trying to save transaction state : callid\n");
|
|
|
+ shm_free(saved_t);
|
|
|
+ return CSCF_RETURN_ERROR;
|
|
|
+ }
|
|
|
+ memset(saved_t->realm.s, 0, realm.len + 1);
|
|
|
+ memcpy(saved_t->realm.s, realm.s, realm.len);
|
|
|
+ saved_t->realm.len = realm.len;
|
|
|
+
|
|
|
+ saved_t->is_proxy_auth = is_proxy_auth;
|
|
|
+ saved_t->is_resync = 1;
|
|
|
+
|
|
|
+ LM_DBG("Suspending SIP TM transaction\n");
|
|
|
+ if (tmb.t_suspend(msg, &saved_t->tindex, &saved_t->tlabel) < 0) {
|
|
|
+ LM_ERR("failed to suspend the TM processing\n");
|
|
|
+ free_saved_transaction_data(saved_t);
|
|
|
+
|
|
|
+ stateful_request_reply(msg, 480, MSG_480_DIAMETER_ERROR);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (multimedia_auth_request(msg, public_identity, private_identity,
|
|
|
+ av_request_at_sync, auth_scheme_types[algo_type], nonce, auts,
|
|
|
+ scscf_name_str, saved_t) != 0) {
|
|
|
+ LM_ERR("ERR:I_MAR: Error sending MAR or MAR time-out\n");
|
|
|
+ tmb.t_cancel_suspend(saved_t->tindex, saved_t->tlabel);
|
|
|
+ free_saved_transaction_data(saved_t);
|
|
|
+ stateful_request_reply(msg, 480, MSG_480_DIAMETER_ERROR);
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+ }
|
|
|
+
|
|
|
+ return CSCF_RETURN_BREAK;
|
|
|
+}
|
|
|
+
|
|
|
int proxy_challenge(struct sip_msg* msg, char* _route, char* str1, char* str2) {
|
|
|
return challenge(msg, str1, str2, 1, _route);
|
|
|
}
|
|
@@ -554,7 +700,7 @@ int authenticate(struct sip_msg* msg, char* _realm, char* str2, int is_proxy_aut
|
|
|
unsigned int aud_hash = 0;
|
|
|
str realm;
|
|
|
str private_identity, public_identity;
|
|
|
- str nonce, response16, nc, cnonce, qop_str = {0, 0}, body, *next_nonce = &empty_s;
|
|
|
+ str nonce, response16, nc, cnonce, qop_str = {0, 0}, auts = {0, 0}, body, *next_nonce = &empty_s;
|
|
|
enum qop_type qop = QOP_UNSPEC;
|
|
|
str uri = {0, 0};
|
|
|
HASHHEX expected, ha1, hbody, rspauth;
|
|
@@ -631,7 +777,7 @@ int authenticate(struct sip_msg* msg, char* _realm, char* str2, int is_proxy_aut
|
|
|
/* if none found, or nonce reuse is disabled, look for a fresh vector
|
|
|
* We should also drop every other used vector at this point
|
|
|
* (there souldn't be more than one) */
|
|
|
-
|
|
|
+ LM_DBG("Looking for auth vector based on IMPI: [%.*s] and IMPU: [%.*s]\n", private_identity.len, private_identity.s, public_identity.len, public_identity.s);
|
|
|
auth_userdata *aud;
|
|
|
auth_vector *av_it;
|
|
|
aud = get_auth_userdata(private_identity, public_identity);
|
|
@@ -815,7 +961,15 @@ int authenticate(struct sip_msg* msg, char* _realm, char* str2, int is_proxy_aut
|
|
|
authenticate_hex_len,authenticate_hex,
|
|
|
authorise_len,
|
|
|
authorise_len, authorise);
|
|
|
- ret = AUTH_INVALID_PASSWORD;
|
|
|
+// /* check for auts in authorization header - if it is then we need to resync */
|
|
|
+ auts = ims_get_auts(msg, realm, is_proxy_auth);
|
|
|
+ if (auts.len) {
|
|
|
+ LM_DBG("IMS Auth Synchronization requested <%.*s>\n", auts.len, auts.s);
|
|
|
+ ret = AUTH_RESYNC_REQUESTED;
|
|
|
+ av->status = AUTH_VECTOR_SENT;
|
|
|
+ } else {
|
|
|
+ ret = AUTH_INVALID_PASSWORD;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (ignore_failed_auth) {
|
|
@@ -1113,6 +1267,8 @@ auth_vector * new_auth_vector(int item_number, str auth_scheme, str authenticate
|
|
|
x->status = AUTH_VECTOR_UNUSED;
|
|
|
x->expires = 0;
|
|
|
|
|
|
+ LM_DBG("new auth-vector with ck [%.*s] with status %d\n", x->ck.len, x->ck.s, x->status);
|
|
|
+
|
|
|
done:
|
|
|
return x;
|
|
|
}
|
|
@@ -1315,26 +1471,28 @@ int multimedia_auth_request(struct sip_msg *msg, str public_identity, str privat
|
|
|
str authorization = {0, 0};
|
|
|
int result = -1;
|
|
|
|
|
|
- //TODO this is MAR syncing - have removed it currently - TOD maybe put back in
|
|
|
- //int is_sync = 0;
|
|
|
-// if (auts.len) {
|
|
|
-// authorization.s = pkg_malloc(nonce.len * 3 / 4 + auts.len * 3 / 4 + 8);
|
|
|
-// if (!authorization.s) goto done;
|
|
|
-// authorization.len = base64_to_bin(nonce.s, nonce.len, authorization.s);
|
|
|
-// authorization.len = RAND_LEN;
|
|
|
-// authorization.len += base64_to_bin(auts.s, auts.len, authorization.s + authorization.len);
|
|
|
-// is_sync = 1;
|
|
|
-// }
|
|
|
+ int is_sync = 0;
|
|
|
+ if (auts.len) {
|
|
|
+ authorization.s = pkg_malloc(nonce.len * 3 / 4 + auts.len * 3 / 4 + 8);
|
|
|
+ if (!authorization.s) {
|
|
|
+ LM_ERR("no more pkg mem\n");
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ authorization.len = base64_to_bin(nonce.s, nonce.len, authorization.s);
|
|
|
+ authorization.len = RAND_LEN;
|
|
|
+ authorization.len += base64_to_bin(auts.s, auts.len, authorization.s + authorization.len);
|
|
|
+ is_sync = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (is_sync) {
|
|
|
+ drop_auth_userdata(private_identity, public_identity);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
LM_DBG("Sending MAR\n");
|
|
|
result = cxdx_send_mar(msg, public_identity, private_identity, count, auth_scheme, authorization, servername, transaction_data);
|
|
|
if (authorization.s) pkg_free(authorization.s);
|
|
|
|
|
|
- //TODO this is MAR syncing - have removed it currently - TOD maybe put back in
|
|
|
- //if (is_sync)
|
|
|
- // drop_auth_userdata(private_identity, public_identity);
|
|
|
-
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -1500,12 +1658,14 @@ int drop_auth_userdata(str private_identity, str public_identity) {
|
|
|
|
|
|
av = aud->head;
|
|
|
while (av) {
|
|
|
+ LM_DBG("dropping auth vector that was in status %d\n", av->status);
|
|
|
av->status = AUTH_VECTOR_USELESS;
|
|
|
av = av->next;
|
|
|
}
|
|
|
auth_data_unlock(aud->hash);
|
|
|
return 1;
|
|
|
error:
|
|
|
+ LM_DBG("no authdata to drop any auth vectors\n");
|
|
|
if (aud) auth_data_unlock(aud->hash);
|
|
|
return 0;
|
|
|
}
|