diff -r 733187d496d0 -r 8ec65b8f6e2c opensips/uac-reauth.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/opensips/uac-reauth.diff Wed Feb 10 21:25:01 2010 +0100 @@ -0,0 +1,211 @@ +Index: modules/uac/auth.c +diff -Nau modules/uac/auth.c.orig modules/uac/auth.c +--- modules/uac/auth.c.orig 2010-01-18 12:32:26.152280000 +0100 ++++ modules/uac/auth.c 2010-02-10 20:25:06.204228079 +0100 +@@ -24,6 +24,7 @@ + * --------- + * 2005-01-31 first version (ramona) + * 2006-03-02 UAC authentication looks first in AVPs for credential (bogdan) ++ * 2010-01-18 UAC replaces proxy-auth entries with new credentials (msvb) + */ + + +@@ -375,14 +376,172 @@ + HASHHEX response; + str *new_hdr; + ++ /* pretransact */ ++ int nret = 0; ++ pv_value_t pv_val; ++ str *newuri = 0; ++ struct uac_credential *tst = 0; ++ struct hdr_field *tmp_hdr = 0; ++ struct hdr_field *del_hdr = 0; ++ ++ ++ /* Goes something like this... */ ++ /* HA1 = echo -n 'username:realm:password' | md5sum */ ++ /* echo -n 'itsme:mydom.com:stupidpass' | md5sum */ ++ /* HA2 = echo -n 'message:uri' | md5sum */ ++ /* echo -n 'INVITE:sip:danc@ing.fool.es' | md5sum */ ++ /* Response = echo -n 'HA1:nonce:HA2' | md5sum */ + /* get transaction */ + t = uac_tmb.t_gett(); +- if (t==T_UNDEFINED || t==T_NULL_CELL) +- { +- LM_CRIT("no current transaction found\n"); +- goto error; +- } ++ if (t==T_UNDEFINED || t==T_NULL_CELL) { ++ /* begin without any transaction */ ++ /* set relevant structure variables */ ++ crd = 0; ++ crd = pkg_malloc(sizeof(struct uac_credential)); ++ if (!crd) { ++ LM_ERR("no more pkg memory\n"); ++ goto error; ++ } ++ ++ /* set the realm from existing UAC message */ ++ tmp_hdr = msg->proxy_auth; ++ del_hdr = 0; ++ while (tmp_hdr) { ++ crd->realm.s = strchr(strstr(tmp_hdr->body.s, "realm="), '"') + 1; ++ crd->realm.len = strchr(crd->realm.s, '"') - crd->realm.s; ++ if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ ++ && pv_val.rs.len>0) /* ensure realm is the desired one */ ++ if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) ++ del_hdr = tmp_hdr; ++ tmp_hdr = tmp_hdr->sibling; ++ } ++ if (del_hdr) ++ crd->realm = pv_val.rs; /* success */ ++ else ++ nret++; /* failure */ ++ ++ /* set username from new AVP proxy values */ ++ if(pv_get_spec_value(msg, &auth_username_spec, &pv_val)!=0 \ ++ || pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0) ++ nret++; /* signal failure with nonzero value */ ++ else ++ crd->user = pv_val.rs; ++ ++ /* set password from new AVP proxy values */ ++ if(pv_get_spec_value(msg, &auth_password_spec, &pv_val)!=0 \ ++ || pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0) ++ nret++; /* signal failure with nonzero value */ ++ else ++ crd->passwd = pv_val.rs; ++ ++ if (nret) { /* if not found, look into predefined credentials */ ++ tst = lookup_realm(&crd->realm); ++ ++ if (tst==0) { /* found? */ ++ LM_DBG("no credential for realm \"%.*s\"\n", \ ++ crd->realm.len, crd->realm.s); ++ pkg_free(crd); ++ goto error; ++ } ++ ++ crd = tst; /* use predefined credentials */ ++ /* set the realm from existing UAC message */ ++ tmp_hdr = msg->proxy_auth; ++ del_hdr = 0; ++ while (tmp_hdr) { ++ if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ ++ && pv_val.rs.len>0) /* ensure realm is the desired one */ ++ if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) ++ del_hdr = tmp_hdr; ++ tmp_hdr = tmp_hdr->sibling; ++ } ++ if (del_hdr == 0) { /* proxy-auth header matching realm not found */ ++ LM_DBG("no credential for realm \"%.*s\"\n", \ ++ crd->realm.len, crd->realm.s); ++ pkg_free(crd); ++ goto error; ++ } ++ } ++ ++ /* set the uri from existing UAC message */ ++ newuri = pkg_malloc(sizeof(str)); ++ if (!newuri) { ++ LM_ERR("no more pkg memory\n"); ++ goto error; ++ } ++ newuri->s = pkg_malloc(msg->new_uri.len); ++ if (!newuri->s) { ++ LM_ERR("no more pkg memory\n"); ++ pkg_free(newuri); ++ goto error; ++ } ++ newuri->len = msg->new_uri.len; ++ strncpy(newuri->s, msg->new_uri.s, msg->new_uri.len); ++ if (!newuri->s) { ++ LM_DBG("failed to retrieve URI from UAC message\n"); ++ pkg_free(newuri->s); ++ pkg_free(newuri); ++ goto error; ++ } ++ ++ /* set the nonce from existing UAC message */ ++ tmp_hdr = msg->proxy_auth; ++ auth.nonce.len = 0; ++ auth.nonce.s = 0; ++ while (tmp_hdr) { ++ if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ ++ && pv_val.rs.len>0) /* ensure realm is the desired one */ ++ if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) { ++ auth.nonce.s = strchr(strstr(tmp_hdr->body.s, "nonce="), '"') + 1; ++ auth.nonce.len = strchr(auth.nonce.s, '"') - auth.nonce.s; ++ } ++ tmp_hdr = tmp_hdr->sibling; ++ } ++ if (auth.nonce.s == 0) { ++ LM_DBG("failed to retrieve nonce from UAC message\n"); ++ pkg_free(crd); ++ goto error; ++ } ++ ++ /* do authentication */ ++ do_uac_auth(msg, newuri, crd, &auth, response); ++ if (response==0) { ++ LM_ERR("failed to calculate challenge response\n"); ++ pkg_free(crd); ++ goto error; ++ } ++ ++ /* build the authorization header */ ++ new_hdr = build_authorization_hdr(407, newuri, crd, &auth, response); ++ if (new_hdr==0) { ++ LM_ERR("failed to build authorization hdr\n"); ++ pkg_free(crd); ++ goto error; ++ } ++ ++ /* remove the old proxy-auth header and relink message index */ ++ /* before updating the authorization credentials of the message */ ++ if (del_hdr) { /* updated a record and must remove the old one */ ++ if (del_lump(msg, del_hdr->name.s - msg->buf, del_hdr->len, 0)==0) { ++ LM_ERR("can't remove credentials\n"); ++ pkg_free(crd); ++ goto error; ++ } ++ } ++ ++ /* so far, so good -> add the header and set the proper RURI */ ++ if (apply_urihdr_changes(msg, newuri, new_hdr)<0) ++ { ++ LM_ERR("failed to apply changes\n"); ++ pkg_free(crd); ++ goto error; ++ } ++ ++ pkg_free(crd); /* finished calculating new response string, success */ ++ return 0; ++ } /* if (t==T_UNDEFINED || t==T_NULL_CELL) */ + ++ /* begin with transaction reply */ + /* get the selected branch */ + branch = uac_tmb.t_get_picked(); + if (branch<0) { +Index: modules/uac/uac.c +diff -Nau modules/uac/uac.c.orig modules/uac/uac.c +--- modules/uac/uac.c.orig 2010-01-18 12:32:26.159078000 +0100 ++++ modules/uac/uac.c 2010-02-10 20:25:06.206731656 +0100 +@@ -29,6 +29,7 @@ + * 2006-03-03 the RR parameter is encrypted via XOR with a password + * (bogdan) + * 2009-08-22 TO header replacement added (bogdan) ++ * 2010-01-18 UAC is able to construct credentials from request (msvb) + + */ + +@@ -106,7 +107,7 @@ + REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE }, + {"uac_auth", (cmd_function)w_uac_auth, 0, + 0, 0, +- FAILURE_ROUTE }, ++ REQUEST_ROUTE|FAILURE_ROUTE }, + {0,0,0,0,0,0} + }; +