[Chilli] Bug in password handling - Rev 257 PATCH
David Bird
david at coova.com
Tue Dec 15 18:29:45 UTC 2009
committed as rev 258
thanks
On Tue, 2009-12-15 at 13:46 +0100, Alberto Bellettato wrote:
> Long passwords still did not work with the latest svn rev. 257, so I dug into the code and I found a real problem.
>
> In 3 code's rows, the length of the password string is calculated through strlen(), that considers the first NUL as the end of the string, as you surely know.
>
> But in function redir_hextochar() (redir.c row 78), sscanf() is used to transform the password from hex string to char (row 87).
>
> And here is the big problem:
> the hex password string is the result of the md5() encryption so it _can_ contain the hex '00', that will be converted to NUL by sscanf().
>
> You can easily test it with this example:
>
> --------------------------------------------
> #include <stdio.h>
>
> main () {
> char x[3];
> int y;
> char ds[7];
>
> x[0] = '0';
> x[1] = '0';
> x[2] = 0;
> if (sscanf(x, "%2x", &y) != 1)
> printf("\nError\n");
> ds[0]='s';
> ds[1]='t';
> ds[2]='r';
> ds[3]=(char)y;
> ds[4]='n';
> ds[5]='g';
> ds[6]='\0';
> printf("\n%s\n",ds);
> }
> ----------------------------------------------
>
> The output will be 'str' and NOT 'str0ng' !!
>
> Obviously this problem shows more frequently as the password's length increase because the probability of finding a HEX '00' increases with it.
>
> So I patched the code to remove all the strlen() use with password strings, and I optimized some parts too.
> I tested it with Rev 257 configured with --enable-chilliredir and it works fine with every password length.
> NOTE: if password's length (sent by UAM service) is more than 128 chars (RFC2865 maximum length) it is truncated to the first 128 chars.
>
> Here is the patch for Rev 257:
>
> Index: src/redir.c
> ===================================================================
> --- src/redir.c (revisione 257)
> +++ src/redir.c (copia locale)
> @@ -85,10 +85,8 @@
> x[1] = src[n*2+1];
> x[2] = 0;
> if (sscanf(x, "%2x", &y) != 1) {
> - /*log_err(0, "HEX conversion failed!");
> - return -1;*/
> - dst[n] = 0;
> - break;
> + log_err(0, "HEX conversion failed!");
> + return -1;
> }
> dst[n] = (unsigned char) y;
> }
> @@ -405,7 +403,7 @@
>
> hex[0]=0;
> for (i=0; i<16; i++)
> - sprintf(hex+strlen(hex), "%.2X", cksum[i]);
> + sprintf(hex+2*i, "%.2X", cksum[i]);
>
> bcatcstr(str, amp);
> bcatcstr(str, "md=");
> @@ -1570,8 +1568,11 @@
> conn->password[0] = 0;
> }
> else if (!redir_getparam(redir, httpreq->qs, "password", bt)) {
> - redir_hextochar(bt->data, conn->password, RADIUS_PWSIZE);
> - conn->password[RADIUS_PWSIZE-1]=0;
> + conn->password_len = bt->slen/2;
> + log_dbg("Password length: %d",conn->password_len);
> + if (conn->password_len > RADIUS_PWSIZE)
> + conn->password_len = RADIUS_PWSIZE;
> + redir_hextochar(bt->data, conn->password, conn->password_len);
> conn->chap = 0;
> conn->chappassword[0] = 0;
> } else {
> @@ -1798,7 +1799,7 @@
> for (n=0; n < REDIR_MD5LEN; m++, n++)
> user_password[m] = conn->password[m] ^ chap_challenge[n];
>
> - user_password[strlen((char *)conn->password)] = 0;
> + user_password[conn->password_len] = 0;
>
> #ifdef HAVE_OPENSSL
> if (_options.mschapv2) {
> @@ -1810,7 +1811,7 @@
>
> GenerateNTResponse(chap_challenge, /*peer*/chap_challenge,
> conn->s_state.redir.username, strlen(conn->s_state.redir.username),
> - user_password, strlen(user_password),
> + user_password, conn->password_len,
> ntresponse);
>
> /* peer challenge - same as auth challenge */
> @@ -1831,7 +1832,7 @@
> #endif
>
> radius_addattr(radius, &radius_pack, RADIUS_ATTR_USER_PASSWORD, 0, 0, 0,
> - user_password, strlen((char*)user_password));
> + user_password, conn->password_len);
>
> #ifdef HAVE_OPENSSL
> }
> Index: src/redir.h
> ===================================================================
> --- src/redir.h (revisione 257)
> +++ src/redir.h (copia locale)
> @@ -79,6 +79,7 @@
> int response; /* 0: No radius response yet; 1:Reject; 2:Accept; 3:Timeout */
> uint8_t chappassword[RADIUS_CHAPSIZE];
> uint8_t password[RADIUS_PWSIZE];
> + int password_len;
> uint8_t chap_ident;
>
> /*
> Index: src/radius.c
> ===================================================================
> --- src/radius.c (revisione 257)
> +++ src/radius.c (copia locale)
> @@ -1064,7 +1064,7 @@
> *dstlen = srclen; /* No padding */
>
> /* Is dstsize too small ? */
> - if (dstsize <= *dstlen) {
> + if (dstsize < *dstlen) {
> *dstlen = 0;
> return -1;
> }
>
>
>
> _______________________________________________
> Chilli mailing list
> Chilli at coova.org
> http://lists.coova.org/cgi-bin/mailman/listinfo/chilli
More information about the Chilli
mailing list