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);