auth_httpform password encoding bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

This is a patch I have been sitting on for some time.

I have been upgrading from 2.1.19 to 2.1.23 and I have found that some 
of my patches are still required (and even work).

(These are red hat releases but it seems relevant to the vanilla source 
too).

The first issue is that when using saslauthd with auth_httpform, the 
password is not correctly encoded if it contains a & character. I also 
escape the % which I think is required. Spaces and + might also be a 
problem (untested).

For full correctness, all the expanded parameters should probably be 
correctly encoded as x-www-form-urlencoded
http://www.w3.org/MarkUp/html-spec/html-spec_8.html
I can implement that if anyone is interested but there might be others 
who know the code better.

Regards,

John.


-- 
John Newbigin | ITS Senior Analyst / Programmer
Faculty of Information and Communication Technologies
ITS | Swinburne University of Technology | Melbourne, Australia
O: EN306 | T: +61 3 9214 8185 | M: +61 410 569 362
E: jnewbigin@xxxxxxxxxxx
W: http://www.ict.swin.edu.au/staff/jnewbigin
--- ./cyrus-sasl-2.1.19.http/cyrus-sasl-2.1.19/saslauthd/auth_httpform.c	2010-03-30 14:22:19.000000000 +1100
+++ ./cyrus-sasl-2.1.19/cyrus-sasl-2.1.19/saslauthd/auth_httpform.c	2010-03-30 14:31:34.000000000 +1100
@@ -247,6 +247,9 @@
     ulen = strlen(user);
     plen = strlen(password);
     rlen = strlen(realm);
+
+	/* The password might have '&' in it which we must escape here to %26 so make room*/
+	plen*= 3;
     
     /* what if we have multiple %foo occurrences in the input query? */
     for (i = 0; i < strlen(formdata); i++) {
@@ -288,8 +291,35 @@
             buf_ptr += ulen;
             break;
         case 'p':
-            memcpy(buf_ptr, password, plen);
-            buf_ptr += plen;
+			/* We must copy char by char so we can escape any & character */
+			plen = 0;
+			while(password[plen])
+			{
+				if(password[plen] == '&')
+				{
+					buf_ptr[0] = '%';
+					buf_ptr++;
+					buf_ptr[0] = '2';
+					buf_ptr++;
+					buf_ptr[0] = '6';
+					buf_ptr++;
+				}
+				else if(password[plen] == '%')
+				{
+					buf_ptr[0] = '%';
+					buf_ptr++;
+					buf_ptr[0] = '2';
+					buf_ptr++;
+					buf_ptr[0] = '5';
+					buf_ptr++;
+				}
+				else
+				{
+					buf_ptr[0] = password[plen];
+					buf_ptr++;
+				}
+				plen++;
+			}
             break;
         case 'r':
             memcpy(buf_ptr, realm, rlen);

[Index of Archives]     [Info Cyrus]     [Squirrel Mail]     [Linux Media]     [Yosemite News]     [gtk]     [KDE]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux