Mon, 16 Jan 2012 22:56:52 +0100
Import original vendor code for correction and improvement.
michael@18 | 1 | Index: modules/uac/auth.c |
michael@18 | 2 | diff -Nau modules/uac/auth.c.orig modules/uac/auth.c |
michael@18 | 3 | --- modules/uac/auth.c.orig 2010-01-18 12:32:26.152280000 +0100 |
michael@18 | 4 | +++ modules/uac/auth.c 2010-02-10 20:25:06.204228079 +0100 |
michael@18 | 5 | @@ -24,6 +24,7 @@ |
michael@18 | 6 | * --------- |
michael@18 | 7 | * 2005-01-31 first version (ramona) |
michael@18 | 8 | * 2006-03-02 UAC authentication looks first in AVPs for credential (bogdan) |
michael@18 | 9 | + * 2010-01-18 UAC replaces proxy-auth entries with new credentials (msvb) |
michael@18 | 10 | */ |
michael@18 | 11 | |
michael@18 | 12 | |
michael@18 | 13 | @@ -375,14 +376,172 @@ |
michael@18 | 14 | HASHHEX response; |
michael@18 | 15 | str *new_hdr; |
michael@18 | 16 | |
michael@18 | 17 | + /* pretransact */ |
michael@18 | 18 | + int nret = 0; |
michael@18 | 19 | + pv_value_t pv_val; |
michael@18 | 20 | + str *newuri = 0; |
michael@18 | 21 | + struct uac_credential *tst = 0; |
michael@18 | 22 | + struct hdr_field *tmp_hdr = 0; |
michael@18 | 23 | + struct hdr_field *del_hdr = 0; |
michael@18 | 24 | + |
michael@18 | 25 | + |
michael@18 | 26 | + /* Goes something like this... */ |
michael@18 | 27 | + /* HA1 = echo -n 'username:realm:password' | md5sum */ |
michael@18 | 28 | + /* echo -n 'itsme:mydom.com:stupidpass' | md5sum */ |
michael@18 | 29 | + /* HA2 = echo -n 'message:uri' | md5sum */ |
michael@18 | 30 | + /* echo -n 'INVITE:sip:danc@ing.fool.es' | md5sum */ |
michael@18 | 31 | + /* Response = echo -n 'HA1:nonce:HA2' | md5sum */ |
michael@18 | 32 | /* get transaction */ |
michael@18 | 33 | t = uac_tmb.t_gett(); |
michael@18 | 34 | - if (t==T_UNDEFINED || t==T_NULL_CELL) |
michael@18 | 35 | - { |
michael@18 | 36 | - LM_CRIT("no current transaction found\n"); |
michael@18 | 37 | - goto error; |
michael@18 | 38 | - } |
michael@18 | 39 | + if (t==T_UNDEFINED || t==T_NULL_CELL) { |
michael@18 | 40 | + /* begin without any transaction */ |
michael@18 | 41 | + /* set relevant structure variables */ |
michael@18 | 42 | + crd = 0; |
michael@18 | 43 | + crd = pkg_malloc(sizeof(struct uac_credential)); |
michael@18 | 44 | + if (!crd) { |
michael@18 | 45 | + LM_ERR("no more pkg memory\n"); |
michael@18 | 46 | + goto error; |
michael@18 | 47 | + } |
michael@18 | 48 | + |
michael@18 | 49 | + /* set the realm from existing UAC message */ |
michael@18 | 50 | + tmp_hdr = msg->proxy_auth; |
michael@18 | 51 | + del_hdr = 0; |
michael@18 | 52 | + while (tmp_hdr) { |
michael@18 | 53 | + crd->realm.s = strchr(strstr(tmp_hdr->body.s, "realm="), '"') + 1; |
michael@18 | 54 | + crd->realm.len = strchr(crd->realm.s, '"') - crd->realm.s; |
michael@18 | 55 | + if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ |
michael@18 | 56 | + && pv_val.rs.len>0) /* ensure realm is the desired one */ |
michael@18 | 57 | + if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) |
michael@18 | 58 | + del_hdr = tmp_hdr; |
michael@18 | 59 | + tmp_hdr = tmp_hdr->sibling; |
michael@18 | 60 | + } |
michael@18 | 61 | + if (del_hdr) |
michael@18 | 62 | + crd->realm = pv_val.rs; /* success */ |
michael@18 | 63 | + else |
michael@18 | 64 | + nret++; /* failure */ |
michael@18 | 65 | + |
michael@18 | 66 | + /* set username from new AVP proxy values */ |
michael@18 | 67 | + if(pv_get_spec_value(msg, &auth_username_spec, &pv_val)!=0 \ |
michael@18 | 68 | + || pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0) |
michael@18 | 69 | + nret++; /* signal failure with nonzero value */ |
michael@18 | 70 | + else |
michael@18 | 71 | + crd->user = pv_val.rs; |
michael@18 | 72 | + |
michael@18 | 73 | + /* set password from new AVP proxy values */ |
michael@18 | 74 | + if(pv_get_spec_value(msg, &auth_password_spec, &pv_val)!=0 \ |
michael@18 | 75 | + || pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0) |
michael@18 | 76 | + nret++; /* signal failure with nonzero value */ |
michael@18 | 77 | + else |
michael@18 | 78 | + crd->passwd = pv_val.rs; |
michael@18 | 79 | + |
michael@18 | 80 | + if (nret) { /* if not found, look into predefined credentials */ |
michael@18 | 81 | + tst = lookup_realm(&crd->realm); |
michael@18 | 82 | + |
michael@18 | 83 | + if (tst==0) { /* found? */ |
michael@18 | 84 | + LM_DBG("no credential for realm \"%.*s\"\n", \ |
michael@18 | 85 | + crd->realm.len, crd->realm.s); |
michael@18 | 86 | + pkg_free(crd); |
michael@18 | 87 | + goto error; |
michael@18 | 88 | + } |
michael@18 | 89 | + |
michael@18 | 90 | + crd = tst; /* use predefined credentials */ |
michael@18 | 91 | + /* set the realm from existing UAC message */ |
michael@18 | 92 | + tmp_hdr = msg->proxy_auth; |
michael@18 | 93 | + del_hdr = 0; |
michael@18 | 94 | + while (tmp_hdr) { |
michael@18 | 95 | + if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ |
michael@18 | 96 | + && pv_val.rs.len>0) /* ensure realm is the desired one */ |
michael@18 | 97 | + if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) |
michael@18 | 98 | + del_hdr = tmp_hdr; |
michael@18 | 99 | + tmp_hdr = tmp_hdr->sibling; |
michael@18 | 100 | + } |
michael@18 | 101 | + if (del_hdr == 0) { /* proxy-auth header matching realm not found */ |
michael@18 | 102 | + LM_DBG("no credential for realm \"%.*s\"\n", \ |
michael@18 | 103 | + crd->realm.len, crd->realm.s); |
michael@18 | 104 | + pkg_free(crd); |
michael@18 | 105 | + goto error; |
michael@18 | 106 | + } |
michael@18 | 107 | + } |
michael@18 | 108 | + |
michael@18 | 109 | + /* set the uri from existing UAC message */ |
michael@18 | 110 | + newuri = pkg_malloc(sizeof(str)); |
michael@18 | 111 | + if (!newuri) { |
michael@18 | 112 | + LM_ERR("no more pkg memory\n"); |
michael@18 | 113 | + goto error; |
michael@18 | 114 | + } |
michael@18 | 115 | + newuri->s = pkg_malloc(msg->new_uri.len); |
michael@18 | 116 | + if (!newuri->s) { |
michael@18 | 117 | + LM_ERR("no more pkg memory\n"); |
michael@18 | 118 | + pkg_free(newuri); |
michael@18 | 119 | + goto error; |
michael@18 | 120 | + } |
michael@18 | 121 | + newuri->len = msg->new_uri.len; |
michael@18 | 122 | + strncpy(newuri->s, msg->new_uri.s, msg->new_uri.len); |
michael@18 | 123 | + if (!newuri->s) { |
michael@18 | 124 | + LM_DBG("failed to retrieve URI from UAC message\n"); |
michael@18 | 125 | + pkg_free(newuri->s); |
michael@18 | 126 | + pkg_free(newuri); |
michael@18 | 127 | + goto error; |
michael@18 | 128 | + } |
michael@18 | 129 | + |
michael@18 | 130 | + /* set the nonce from existing UAC message */ |
michael@18 | 131 | + tmp_hdr = msg->proxy_auth; |
michael@18 | 132 | + auth.nonce.len = 0; |
michael@18 | 133 | + auth.nonce.s = 0; |
michael@18 | 134 | + while (tmp_hdr) { |
michael@18 | 135 | + if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \ |
michael@18 | 136 | + && pv_val.rs.len>0) /* ensure realm is the desired one */ |
michael@18 | 137 | + if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) { |
michael@18 | 138 | + auth.nonce.s = strchr(strstr(tmp_hdr->body.s, "nonce="), '"') + 1; |
michael@18 | 139 | + auth.nonce.len = strchr(auth.nonce.s, '"') - auth.nonce.s; |
michael@18 | 140 | + } |
michael@18 | 141 | + tmp_hdr = tmp_hdr->sibling; |
michael@18 | 142 | + } |
michael@18 | 143 | + if (auth.nonce.s == 0) { |
michael@18 | 144 | + LM_DBG("failed to retrieve nonce from UAC message\n"); |
michael@18 | 145 | + pkg_free(crd); |
michael@18 | 146 | + goto error; |
michael@18 | 147 | + } |
michael@18 | 148 | + |
michael@18 | 149 | + /* do authentication */ |
michael@18 | 150 | + do_uac_auth(msg, newuri, crd, &auth, response); |
michael@18 | 151 | + if (response==0) { |
michael@18 | 152 | + LM_ERR("failed to calculate challenge response\n"); |
michael@18 | 153 | + pkg_free(crd); |
michael@18 | 154 | + goto error; |
michael@18 | 155 | + } |
michael@18 | 156 | + |
michael@18 | 157 | + /* build the authorization header */ |
michael@18 | 158 | + new_hdr = build_authorization_hdr(407, newuri, crd, &auth, response); |
michael@18 | 159 | + if (new_hdr==0) { |
michael@18 | 160 | + LM_ERR("failed to build authorization hdr\n"); |
michael@18 | 161 | + pkg_free(crd); |
michael@18 | 162 | + goto error; |
michael@18 | 163 | + } |
michael@18 | 164 | + |
michael@18 | 165 | + /* remove the old proxy-auth header and relink message index */ |
michael@18 | 166 | + /* before updating the authorization credentials of the message */ |
michael@18 | 167 | + if (del_hdr) { /* updated a record and must remove the old one */ |
michael@18 | 168 | + if (del_lump(msg, del_hdr->name.s - msg->buf, del_hdr->len, 0)==0) { |
michael@18 | 169 | + LM_ERR("can't remove credentials\n"); |
michael@18 | 170 | + pkg_free(crd); |
michael@18 | 171 | + goto error; |
michael@18 | 172 | + } |
michael@18 | 173 | + } |
michael@18 | 174 | + |
michael@18 | 175 | + /* so far, so good -> add the header and set the proper RURI */ |
michael@18 | 176 | + if (apply_urihdr_changes(msg, newuri, new_hdr)<0) |
michael@18 | 177 | + { |
michael@18 | 178 | + LM_ERR("failed to apply changes\n"); |
michael@18 | 179 | + pkg_free(crd); |
michael@18 | 180 | + goto error; |
michael@18 | 181 | + } |
michael@18 | 182 | + |
michael@18 | 183 | + pkg_free(crd); /* finished calculating new response string, success */ |
michael@18 | 184 | + return 0; |
michael@18 | 185 | + } /* if (t==T_UNDEFINED || t==T_NULL_CELL) */ |
michael@18 | 186 | |
michael@18 | 187 | + /* begin with transaction reply */ |
michael@18 | 188 | /* get the selected branch */ |
michael@18 | 189 | branch = uac_tmb.t_get_picked(); |
michael@18 | 190 | if (branch<0) { |
michael@18 | 191 | Index: modules/uac/uac.c |
michael@18 | 192 | diff -Nau modules/uac/uac.c.orig modules/uac/uac.c |
michael@18 | 193 | --- modules/uac/uac.c.orig 2010-01-18 12:32:26.159078000 +0100 |
michael@18 | 194 | +++ modules/uac/uac.c 2010-02-10 20:25:06.206731656 +0100 |
michael@18 | 195 | @@ -29,6 +29,7 @@ |
michael@18 | 196 | * 2006-03-03 the RR parameter is encrypted via XOR with a password |
michael@18 | 197 | * (bogdan) |
michael@18 | 198 | * 2009-08-22 TO header replacement added (bogdan) |
michael@18 | 199 | + * 2010-01-18 UAC is able to construct credentials from request (msvb) |
michael@18 | 200 | |
michael@18 | 201 | */ |
michael@18 | 202 | |
michael@18 | 203 | @@ -106,7 +107,7 @@ |
michael@18 | 204 | REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE }, |
michael@18 | 205 | {"uac_auth", (cmd_function)w_uac_auth, 0, |
michael@18 | 206 | 0, 0, |
michael@18 | 207 | - FAILURE_ROUTE }, |
michael@18 | 208 | + REQUEST_ROUTE|FAILURE_ROUTE }, |
michael@18 | 209 | {0,0,0,0,0,0} |
michael@18 | 210 | }; |
michael@18 | 211 |