Monday, January 18, 2010

The beauty of open source ... in Apache

There is a bug/feature in mod_headers that replaces all finishing line characters with blanks whenever you use mod_headers directive "set".
Most of the times this is OK, but when using SSL this can lead to problems parsing a PEM client certificate.
Because when you pass the client certificate to the application, you get a certificate with spaces in between. This is not the way an https accelerator would work.

That is when you have something like this in the httpd.conf


< Location /headers/ >
SSLOptions +ExportCertData
SSLVerifyClient require
SSLCACertificateFile /my/software/httpd/conf/ca.crt
RequestHeader set SSL-CLIENTCERT-PEM "%{SSL_CLIENT_CERT}e"
ProxyPass http://127.0.0.1:8080/headers/
ProxyPassReverse http://127.0.0.1:8080/headers/
< /Location >


And headers is an example web application (tomcat in my case) to output all http headers. (Not included in this post)

To fix this we have to remove all finishing line characters instead of replacing them with blanks. Here is the source code fix for this.

Apply this patch running patch:

patch mod_headers.c < /tmp/patch.txt


/tmp/patch
----------------------------------------------------------------------------------

-- httpd-2.2.14/modules/metadata/mod_headers.c 2010-01-15 09:08:01.544368411 +0100
+++ temp/httpd-2.2.14/modules/metadata/mod_headers.c 2009-05-04 22:40:20.000000000 +0200
@@ -178,17 +178,13 @@
{
if (ap_strchr_c(hdr, APR_ASCII_LF) || ap_strchr_c(hdr, APR_ASCII_CR)) {
char *ptr;
- char *ret;

- ret = ptr = apr_palloc(p, strlen(hdr)+1);
+ hdr = ptr = apr_pstrdup(p, hdr);

- while (*hdr){
- if (*hdr != APR_ASCII_LF && *hdr != APR_ASCII_CR)
- *ptr++ = *hdr;
- ++hdr;
- }
- *ptr = 0;
- hdr = ret;
+ do {
+ if (*ptr == APR_ASCII_LF || *ptr == APR_ASCII_CR)
+ *ptr = APR_ASCII_BLANK;
+ } while (*ptr++);
}
return hdr;
}

--------------------------------------------------------------------------------------------------

./configure
make
make install
profit!!

Your welcome.

No comments: