Skip Menu |

This queue is for tickets about the Crypt-SSLeay CPAN distribution.

Report information
The Basics
Id: 33954
Status: resolved
Priority: 0/
Queue: Crypt-SSLeay

People
Owner: nanis [...] runu.moc.invalid
Requestors: martin.waite [...] datacash.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.57
Fixed in:
  • 0.57_02
  • 0.57_03
  • 0.57_04



Subject: CONNECT is not robust to fragmentation of HTTP headers
Date: Mon, 10 Mar 2008 12:07:06 +0000
To: bug-Crypt-SSLeay [...] rt.cpan.org
From: Martin Waite <martin.waite [...] datacash.com>
Hi,

Version Crypt-SSLeay-0.57

In lib/Net/SSL.pm, sub proxy_connect_helper, an attempt is made to read the HTTP headers from the proxy server:

Show quoted text
    my $header;
    my $n = $self->SUPER::sysread($header, 8192);
    my $conn_ok = ($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) ? 1 : 0;

    if (not $conn_ok) {
        croak("PROXY ERROR HEADER, could be non-SSL URL:\n$header");
    }
  


For our system, using apache 2 as an SSL proxy, the 2 HTTP headers (and
a blank line) are returned:

Show quoted text
HTTP/1.0 200 Connection establishedCRLF
Proxy-agent: ApacheCRLF
CRLF
  

Apache appears to send the headers in two separate TCP packets.  Mostly, this isn't a problem because by time proxy_connect_helper attempts to read the header, the whole header is available in the O/S buffer.  Sometimes, however, the second header hasn't arrived by time the read takes place.  When this happens, proxy_connect_helper only removes the first header line from the read buffer, and the remainder of the header is read in by OpenSSL, which causes the hand-shaking to fail.

What I think
proxy_connect_helper should do is read until it finds the end of the HTTP headers (CRLF CRLF).  This might take many reads, not just a single one. 

--
Martin Waite
Solutions Architect
DataCash

Tel (Direct): +44 (0)131 538 8431
Mobile: +44 (0)7866 750509

DataCash Ltd, Suite 3/1 Great Michael House,
14 Links Place, Edinburgh, EH6 7EZ, United Kingdom.

Tel: +44 (0)870 7274 762
Fax: +44 (0)870 7274 782

www.datacash.com

DISCLAIMER: This email and any files transmitted with it are confidential to DataCash Group plc and its group companies. It is intended only for the person to whom it is addressed. If you have received this email in error, please forward it to info@datacash.com with the subject line "Received in Error". If you are not the intended recipient you must not use, disclose, copy, print, distribute or rely on this email or any transmitted files. DataCash Ltd is registered in England and Wales no. 3430157. DataCash Ltd is part of the DataCash Group plc. DataCash Group plc is registered in England and Wales no. 3168091. DataCash Ltd and DataCash Group plc registered address is Descartes House, 8 Gate Street, London, WC2A 3HP, United Kingdom.

Save a tree...Please only print this page if essential
Subject: Re: [rt.cpan.org #33954] AutoReply: CONNECT is not robust to fragmentation of HTTP headers
Date: Mon, 10 Mar 2008 18:08:45 +0000
To: bug-Crypt-SSLeay [...] rt.cpan.org
From: Martin Waite <martin.waite [...] datacash.com>
Hi,

Here is a patch for reading the entire HTTP header from the proxy server:
--- /usr/lib/perl5/Net/SSL.pm   2003-05-28 07:26:08.000000000 +0100
+++ Net/SSL.pm  2008-03-10 18:02:11.000000000 +0000
@@ -370,8 +370,11 @@
     $connect_string .= $CRLF;

     $self->SUPER::send($connect_string);
-    my $header;
-    my $n = $self->SUPER::sysread($header, 8192);
+    my $header='';
+    while ( $header !~ /$CRLF$CRLF/ ) {
+      my $n = $self->SUPER::sysread($header, 8192, length($header));
+    }
+
     if($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) {
        $conn_ok = 1;
     }

--
Martin Waite
Solutions Architect
DataCash

Tel (Direct): +44 (0)131 538 8431
Mobile: +44 (0)7866 750509

DataCash Ltd, Suite 3/1 Great Michael House,
14 Links Place, Edinburgh, EH6 7EZ, United Kingdom.

Tel: +44 (0)870 7274 762
Fax: +44 (0)870 7274 782

www.datacash.com

DISCLAIMER: This email and any files transmitted with it are confidential to DataCash Group plc and its group companies. It is intended only for the person to whom it is addressed. If you have received this email in error, please forward it to info@datacash.com with the subject line "Received in Error". If you are not the intended recipient you must not use, disclose, copy, print, distribute or rely on this email or any transmitted files. DataCash Ltd is registered in England and Wales no. 3430157. DataCash Ltd is part of the DataCash Group plc. DataCash Group plc is registered in England and Wales no. 3168091. DataCash Ltd and DataCash Group plc registered address is Descartes House, 8 Gate Street, London, WC2A 3HP, United Kingdom.

Save a tree...Please only print this page if essential
On Mon Mar 10 14:09:09 2008, martin.waite@datacash.com wrote: Show quoted text
> Hi, > > Here is a patch for reading the entire HTTP header from the proxy > server:
Dear Martin, thank-you very much for this patch. I will integrate it into my local repo and release 0.57_02. I don't suppose you know how I could add a test case for this? Connecting to a site that returns a large number of headers? Regards, David Show quoted text
> --- /usr/lib/perl5/Net/SSL.pm 2003-05-28 07:26:08.000000000 +0100 > +++ Net/SSL.pm 2008-03-10 18:02:11.000000000 +0000 > @@ -370,8 +370,11 @@ > $connect_string .= $CRLF; > > $self->SUPER::send($connect_string); > - my $header; > - my $n = $self->SUPER::sysread($header, 8192); > + my $header=''; > + while ( $header !~ /$CRLF$CRLF/ ) { > + my $n = $self->SUPER::sysread($header, 8192, length($header)); > + } > + > if($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) { > $conn_ok = 1; > } > > > -- > Martin Waite > Solutions Architect > DataCash > > Tel (Direct): +44 (0)131 538 8431 > Mobile: +44 (0)7866 750509 > > DataCash Ltd, Suite 3/1 Great Michael House, > 14 Links Place, Edinburgh, EH6 7EZ, United Kingdom. > > Tel: +44 (0)870 7274 762 > Fax: +44 (0)870 7274 782 > > www.datacash.com > > DISCLAIMER: This email and any files transmitted with it are > confidential to > DataCash Group plc and its group companies. It is intended only for > the person > to whom it is addressed. If you have received this email in error, > please > forward it to info@datacash.com with the subject line "Received in > Error". If > you are not the intended recipient you must not use, disclose, copy, > print, > distribute or rely on this email or any transmitted files. DataCash > Ltd is > registered in England and Wales no. 3430157. DataCash Ltd is part of > the > DataCash Group plc. DataCash Group plc is registered in England and > Wales no. > 3168091. DataCash Ltd and DataCash Group plc registered address is > Descartes > House, 8 Gate Street, London, WC2A 3HP, United Kingdom. > Save a tree...Please only print this page if essential
Subject: Re: [rt.cpan.org #33954] CONNECT is not robust to fragmentation of HTTP headers
Date: Mon, 31 Mar 2008 09:24:40 +0100
To: bug-Crypt-SSLeay [...] rt.cpan.org
From: Martin Waite <martin.waite [...] datacash.com>
Hi David,

Sorry - I couldn't come up with a test case.

We found the problem in connecting to Apache 2 proxies across MPLS - which has only 4mps bandwidth.  We found we could use Apache 1.3 proxies with no problem, and even Apache 2 across the local network, but had a 90% failure rate when using Apache2 proxies across the slow link.

All I can think of is recording the packet flow through an SSL handshake, and writing a test server to replay that at slow speed. 

Timing problems are pretty difficult to embody in a test harness.

regards,
Martin

David Landgren via RT wrote: Show quoted text
<URL: http://rt.cpan.org/Ticket/Display.html?id=33954 >

On Mon Mar 10 14:09:09 2008, martin.waite@datacash.com wrote:
  
 Hi,

Here is a patch for reading the entire HTTP header from the proxy
server:
    
Dear Martin,

thank-you very much for this patch. I will integrate it into my local
repo and release 0.57_02.

I don't suppose you know how I could add a test case for this?
Connecting to a site that returns a large number of headers?

Regards,
David

  
--- /usr/lib/perl5/Net/SSL.pm   2003-05-28 07:26:08.000000000 +0100
+++ Net/SSL.pm  2008-03-10 18:02:11.000000000 +0000
@@ -370,8 +370,11 @@
     $connect_string .= $CRLF;

     $self->SUPER::send($connect_string);
-    my $header;
-    my $n = $self->SUPER::sysread($header, 8192);
+    my $header='';
+    while ( $header !~ /$CRLF$CRLF/ ) {
+      my $n = $self->SUPER::sysread($header, 8192, length($header));
+    }
+
     if($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) {
        $conn_ok = 1;
     }


--
Martin Waite
Solutions Architect
DataCash

Tel (Direct): +44 (0)131 538 8431
Mobile: +44 (0)7866 750509

DataCash Ltd, Suite 3/1 Great Michael House,
14 Links Place, Edinburgh, EH6 7EZ, United Kingdom.

Tel: +44 (0)870 7274 762
Fax: +44 (0)870 7274 782

www.datacash.com

DISCLAIMER: This email and any files transmitted with it are
confidential to
DataCash Group plc and its group companies. It is intended only for
the person
to whom it is addressed. If you have received this email in error,
please
forward it to info@datacash.com with the subject line "Received in
Error". If
you are not the intended recipient you must not use, disclose, copy,
print,
distribute or rely on this email or any transmitted files. DataCash
Ltd is
registered in England and Wales no. 3430157. DataCash Ltd is part of
the
DataCash Group plc. DataCash Group plc is registered in England and
Wales no.
3168091. DataCash Ltd and DataCash Group plc registered address is
Descartes
House, 8 Gate Street, London, WC2A 3HP, United Kingdom.
Save a tree...Please only print this page if essential
    



  


--
Martin Waite
Solutions Architect
DataCash

Tel (Direct): +44 (0)131 538 8431
Mobile: +44 (0)7866 750509

DataCash Ltd, Suite 3/1 Great Michael House,
14 Links Place, Edinburgh, EH6 7EZ, United Kingdom.

Tel: +44 (0)870 7274 762
Fax: +44 (0)870 7274 782

www.datacash.com

DISCLAIMER: This email and any files transmitted with it are confidential to DataCash Group plc and its group companies. It is intended only for the person to whom it is addressed. If you have received this email in error, please forward it to info@datacash.com with the subject line "Received in Error". If you are not the intended recipient you must not use, disclose, copy, print, distribute or rely on this email or any transmitted files. DataCash Ltd is registered in England and Wales no. 3430157. DataCash Ltd is part of the DataCash Group plc. DataCash Group plc is registered in England and Wales no. 3168091. DataCash Ltd and DataCash Group plc registered address is Descartes House, 8 Gate Street, London, WC2A 3HP, United Kingdom.

Save a tree...Please only print this page if essential
Subject: RE: [rt.cpan.org #33954] CONNECT is not robust to fragmentation of HTTP headers
Date: Mon, 1 Feb 2010 15:42:11 -0000
To: <bug-Crypt-SSLeay [...] rt.cpan.org>
From: "Martin Waite" <Martin.Waite [...] datacash.com>
Hi David, We have come across a bug in the patch I submitted nearly two years ago. --- /usr/lib/perl5/Net/SSL.pm 2003-05-28 07:26:08.000000000 +0100 +++ Net/SSL.pm 2008-03-10 18:02:11.000000000 +0000 @@ -370,8 +370,11 @@ $connect_string .= $CRLF; $self->SUPER::send($connect_string); - my $header; - my $n = $self->SUPER::sysread($header, 8192); + my $header=''; + while ( $header !~ /$CRLF$CRLF/ ) { + my $n = $self->SUPER::sysread($header, 8192, length($header)); + break if ( $n == 0 ); + } + if($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) { $conn_ok = 1; } The extra line "break if ($n==0)" is required to prevent entering a tight infinite loop if the connection has been severed before the headers have been read. regards, Martin Show quoted text
-----Original Message----- From: David Landgren via RT [mailto:bug-Crypt-SSLeay@rt.cpan.org] Sent: 24 March 2008 11:12 To: martin.waite@datacash.com Subject: [rt.cpan.org #33954] CONNECT is not robust to fragmentation of HTTP headers <URL: http://rt.cpan.org/Ticket/Display.html?id=33954 > On Mon Mar 10 14:09:09 2008, martin.waite@datacash.com wrote:
> Hi, > > Here is a patch for reading the entire HTTP header from the proxy > server:
Dear Martin, thank-you very much for this patch. I will integrate it into my local repo and release 0.57_02. I don't suppose you know how I could add a test case for this? Connecting to a site that returns a large number of headers? Regards, David
> --- /usr/lib/perl5/Net/SSL.pm 2003-05-28 07:26:08.000000000 +0100 > +++ Net/SSL.pm 2008-03-10 18:02:11.000000000 +0000 > @@ -370,8 +370,11 @@ > $connect_string .= $CRLF; > > $self->SUPER::send($connect_string); > - my $header; > - my $n = $self->SUPER::sysread($header, 8192); > + my $header=''; > + while ( $header !~ /$CRLF$CRLF/ ) { > + my $n = $self->SUPER::sysread($header, 8192, length($header)); > + } > + > if($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) { > $conn_ok = 1; > } > > > -- > Martin Waite > Solutions Architect > DataCash > > Tel (Direct): +44 (0)131 538 8431 > Mobile: +44 (0)7866 750509 > > DataCash Ltd, Suite 3/1 Great Michael House, > 14 Links Place, Edinburgh, EH6 7EZ, United Kingdom. > > Tel: +44 (0)870 7274 762 > Fax: +44 (0)870 7274 782 > > www.datacash.com > > DISCLAIMER: This email and any files transmitted with it are > confidential to > DataCash Group plc and its group companies. It is intended only for > the person > to whom it is addressed. If you have received this email in error, > please > forward it to info@datacash.com with the subject line "Received in > Error". If > you are not the intended recipient you must not use, disclose, copy, > print, > distribute or rely on this email or any transmitted files. DataCash > Ltd is > registered in England and Wales no. 3430157. DataCash Ltd is part of > the > DataCash Group plc. DataCash Group plc is registered in England and > Wales no. > 3168091. DataCash Ltd and DataCash Group plc registered address is > Descartes > House, 8 Gate Street, London, WC2A 3HP, United Kingdom. > Save a tree...Please only print this page if essential
From: brian [...] Awfulhak.org
On Mon Feb 01 10:42:44 2010, martin.waite@datacash.com wrote: Show quoted text
> Hi David, > > We have come across a bug in the patch I submitted nearly > two years ago.
[.....] I have a similar patch here: --- lib/Net/SSL.pm.orig 2007-09-17 12:56:52.000000000 -0700 +++ lib/Net/SSL.pm 2010-05-19 11:23:50.000000000 -0700 @@ -361,8 +361,15 @@ $connect_string .= $CRLF; $self->SUPER::send($connect_string); - my $header; - my $n = $self->SUPER::sysread($header, 8192); + my $header = ""; + my $timeout; + while ($header !~ m{HTTP/\d+\.\d+\s+200\s+.*\r\n\r\n}s) { + $timeout = $self->timeout(5) unless length $header; + my $n = $self->SUPER::sysread($header, 8192, length $header); + last if $n <= 0; + } + $self->timeout($timeout) if defined $timeout; + my $conn_ok = ($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) ? 1 : 0; if (not $conn_ok) { As there doesn't seem to be any sign of an update to Crypt-SSLeay, I'll submit this to the FreeBSD ports tree for now. FWIW, the bug is caused by apache's proxy and doesn't occur with other proxies such as squid. It is due to apache writing the "HTTP/1.0 200 ...\r\n" with one write call and the "Proxy-access ...\r\n\r\n" with a second, sending two packets to the client on slow hardware. The receiving Crypt-SSLeay code is satisfied with the first string and doesn't keep reading 'till the \r\n\r\n. The subsequent openssl protocol negotiation that takes place on the same descriptor then fails with a protocol error because it cannot interpret "Proxy-a" (the first 7 bytes) as a reponse to it's client hello.
Subject: RE: [rt.cpan.org #33954] CONNECT is not robust to fragmentation of HTTP headers
Date: Thu, 20 May 2010 08:57:20 +0100
To: <bug-Crypt-SSLeay [...] rt.cpan.org>
From: "Martin Waite" <Martin.Waite [...] datacash.com>
Hi Brian, The patch looks good. This problem showed up in our environment where the perl app and the proxy were in different data centres. The link between data centres was just slow enough for the separate packets to require separate reads. Where the app was in the same data centre as the proxy, there was no problem. regards, Martin Show quoted text
-----Original Message----- From: Brian Somers via RT [mailto:bug-Crypt-SSLeay@rt.cpan.org] Sent: 19 May 2010 19:25 To: Martin Waite Subject: [rt.cpan.org #33954] CONNECT is not robust to fragmentation of HTTP headers <URL: https://rt.cpan.org/Ticket/Display.html?id=33954 > On Mon Feb 01 10:42:44 2010, martin.waite@datacash.com wrote:
> Hi David, > > We have come across a bug in the patch I submitted nearly > two years ago.
[.....] I have a similar patch here: --- lib/Net/SSL.pm.orig 2007-09-17 12:56:52.000000000 -0700 +++ lib/Net/SSL.pm 2010-05-19 11:23:50.000000000 -0700 @@ -361,8 +361,15 @@ $connect_string .= $CRLF; $self->SUPER::send($connect_string); - my $header; - my $n = $self->SUPER::sysread($header, 8192); + my $header = ""; + my $timeout; + while ($header !~ m{HTTP/\d+\.\d+\s+200\s+.*\r\n\r\n}s) { + $timeout = $self->timeout(5) unless length $header; + my $n = $self->SUPER::sysread($header, 8192, length $header); + last if $n <= 0; + } + $self->timeout($timeout) if defined $timeout; + my $conn_ok = ($header =~ /HTTP\/\d+\.\d+\s+200\s+/is) ? 1 : 0; if (not $conn_ok) { As there doesn't seem to be any sign of an update to Crypt-SSLeay, I'll submit this to the FreeBSD ports tree for now. FWIW, the bug is caused by apache's proxy and doesn't occur with other proxies such as squid. It is due to apache writing the "HTTP/1.0 200 ...\r\n" with one write call and the "Proxy-access ...\r\n\r\n" with a second, sending two packets to the client on slow hardware. The receiving Crypt-SSLeay code is satisfied with the first string and doesn't keep reading 'till the \r\n\r\n. The subsequent openssl protocol negotiation that takes place on the same descriptor then fails with a protocol error because it cannot interpret "Proxy-a" (the first 7 bytes) as a reponse to it's client hello.
I haven't been watching this distro, but if I don't hear from David I'll apply this patch and send out a new dev release.