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