one sip ua sent this kind of authorization header:
Authorization: Digest
username="foo",realm="bar",uri="xxx",response="e439fa7438452da7d50690f2268be16f",nonce="4d8060d2000041b2430e64fe7ec681d8fb5709e9c72b8a01",qop=auth,cnonce="0004ccb0",nc=000060a2.
and sr auth module didn't like it but emitted error message
FIXME:check_nonce: bad nc value. i went and checked the code and found
this:
if (nc_enabled && (pf & NF_VALID_NC_ID) && auth->digest.nc.s
&&
auth->digest.nc.len){
if (str2int(&auth->digest.nc, &nc)!=0){
/* error, bad nc */
ERR("FIXME:check_nonce: bad nc value %.*s\n",
auth->digest.nc.len, auth->digest.nc.s);
return 5; /* invalid nc */
}
i.e., looks like it is using str2int to convert to nc value to int. the
problem is that str2int only handles decimal strings, whereas nc value
is a hex string.
am i dreaming or what?
-- juha
Show replies by date
below is my fix to this what i consider (unless proven otherwise) a
major bug. UAs that now fail with sr auth module, worked fine in k.
if there is no misunderstanding and this is a real bug, can someone
please check the fix and commit it asap.
-- juha
*** /usr/src/orig/sip-router/modules/auth/nonce.c 2011-03-13 00:22:46.000000000 +0200
--- nonce.c 2011-03-16 10:21:50.000000000 +0200
***************
*** 276,282 ****
--- 276,299 ----
*/
#define is_bin_nonce_stale(b_nonce, t) (get_bin_nonce_expire(b_nonce) < (t))
+ static inline int l8hex2int(char* _s, unsigned int *_r)
+ {
+ unsigned int i, res = 0;
+ for(i = 0; i < 8; i++) {
+ res *= 16;
+ if ((_s[i] >= '0') && (_s[i] <= '9')) {
+ res += _s[i] - '0';
+ } else if ((_s[i] >= 'a') && (_s[i] <= 'f')) {
+ res += _s[i] - 'a' + 10;
+ } else if ((_s[i] >= 'A') && (_s[i] <= 'F')) {
+ res += _s[i] - 'A' + 10;
+ } else return -1;
+ }
+
+ *_r = res;
+ return 0;
+ }
/** Check whether the nonce returned by UA is valid.
***************
*** 404,415 ****
/* if nounce-count checks enabled & auth. headers has nc */
if (nc_enabled && (pf & NF_VALID_NC_ID) && auth->digest.nc.s
&&
auth->digest.nc.len){
! if (str2int(&auth->digest.nc, &nc)!=0){
! /* error, bad nc */
! ERR("FIXME:check_nonce: bad nc value %.*s\n",
! auth->digest.nc.len, auth->digest.nc.s);
! return 5; /* invalid nc */
! }
switch(nc_check_val(n_id, pf & NF_POOL_NO_MASK, nc)){
case NC_OK:
/* don't perform extra checks or one-time nonce checks
--- 421,433 ----
/* if nounce-count checks enabled & auth. headers has nc */
if (nc_enabled && (pf & NF_VALID_NC_ID) && auth->digest.nc.s
&&
auth->digest.nc.len){
! if ((auth->digest.nc.len != 8) ||
! l8hex2int(auth->digest.nc.s, &nc) != 0) {
! /* error, bad nc */
! ERR("check_nonce: bad nc value %.*s\n",
! auth->digest.nc.len, auth->digest.nc.s);
! return 5; /* invalid nc */
! }
switch(nc_check_val(n_id, pf & NF_POOL_NO_MASK, nc)){
case NC_OK:
/* don't perform extra checks or one-time nonce checks