NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
SSL + HTTP Proxy does not work


Joined: 16 May 2007
Posts: 4
Reply with quote
Hello *,

Thanks for the NuSOAP library, I'm using it for a long time now for several projects and it works well.

Now I have a new problem that I cannot solve so far: Connecting a service using SSL and a HTTP Proxy server. There seems to be some problem with this, I found related problems in this forum, at the sourceforge site and with google. But none of them had a solution (or proper insight).

Here is what I basically do:
$client = new soapclient("https://host/service.php?wsdl", true, 'proxyhost', $proxport);

...which requests the WSDL from the service.

The symptom is: Nothing happens and after 300s something like this is returned:
HTTP ERROR: cURL ERROR: 35: Unknown SSL protocol error in connection to proxyhost:proxyport...

I used ethereal/wireshark and some strace voodoo to figure out what is going on: The client connects the proxy host (and nothing else), reads /etc/ssl/certs/ca-certificates.crt and sends some encrypted stuff (probably SSL handshake) to the proxy. The proxy never answers and we hit a timeout.

This is reproducable on various sites with different php versions, the http proxy is some squid. My test client is using Debian PHP 4.4.4-9 (cli) with libcurl/7.15.5 OpenSSL/0.9.8e zlib/1.2.3 libidn/0.6.5. NuSOAP version in 0.7.2 as downloaded from sourceforge.

Is this a bug in the soap_transport_http class? It seems that ssl + proxy is the only configuration that uses curl, the other schemes use hand-written http. Is this a simple bug in curl? perhaps it misses an fflush() and writes an incomplete ssl handshake? Can I make soap_transport_http not use curl but built-in ssl? I find configuring the http connectivity rather strange in nusoap.

Thanks a lot for any advice and keep up the good work,

Raimund
View user's profileFind all posts by raimiSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
cURL error 35 tells me that there are problems with SSL protocol.
Either server uses unsigned or self-signed certificate or it expects something more from the client, for example a known certificate.

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
yes, well...


Joined: 16 May 2007
Posts: 4
Reply with quote
I was hoping I analyzed the situiation somehow. Seems the error we're seeing comes from curl lib/ssluse.c:

/* If we e.g. use SSLv2 request-method and the server doesn't like us
* (RST connection etc.), OpenSSL gives no explanation whatsoever and
* the SO_ERROR is also lost.
*/
if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
failf(data, "Unknown SSL protocol error in connection to %s:%d ",
conn->host.name, conn->port);
return rc;
}
/* Could be a CERT problem */

I will now try to contact the Proxy operators. Let's see what kind of SSL they do...
View user's profileFind all posts by raimiSend private message
It's not a proper Proxy request


Joined: 16 May 2007
Posts: 4
Reply with quote
Hello again!

I joined up with the proxy admin to explore the problem more deeply. We now assume that it is actually nusoap's fault: It's not performing a proper proxy request. I used wireshark to sniff the actual packets and compared a "curl --proxy" request with what nusoap is doing.

curl --proxy:
CONNECT host:443
...
SSL-handshake
SSL-secured connection

nusoap with https-proxy:
SSL-handshake (incomplete)

nusoap is requesting something the proxy cannot understand and therefore failing. Another indication for me is that there is no
curl_setopt($curl_handle, CURLOPT_PROXY, $proxy);
inside the nusoap library. I assume the proxy request is hand-crafted wrongly.

Again, any comment is appreciated.

Raimund
View user's profileFind all posts by raimiSend private message
Patch: Make ssl + proxy work


Joined: 16 May 2007
Posts: 4
Reply with quote
Hi!

Here is a patch against nusoap.php that makes proxy requests (with SSL) work with curl work. Questions are:

1) Where is the place to actually send this patch to?
2) Is some development still intended for nusoap?
3) Is there some developer forum/mailing list more appropriate?
4) Can I send more patches? This library needs some overhaul.

Code:

--- nusoap-orig.php     2005-08-04 18:53:00.000000000 +0200
+++ nusoap.php  2007-05-21 14:12:09.000000000 +0200
@@ -2012,6 +2012,7 @@
        var $host = '';
        var $port = '';
        var $path = '';
+    var $proxy = null; // passed to curl
        var $request_method = 'POST';
        var $protocol_version = '1.0';
        var $encoding = '';
@@ -2163,6 +2164,10 @@
                curl_setopt($this->ch, CURLOPT_HEADER, 1);
                // ask for the response output as the return value
                curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
+        // enable proxy if any
+        if ($this->proxy != null) {
+            curl_setopt($this->ch, CURLOPT_PROXY, $this->proxy);
+        }
                // encode
                // We manage this ourselves through headers and encoding
 //             if(function_exists('gzuncompress')){
@@ -2399,9 +2404,7 @@
        * @access   public
        */
        function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
-               $this->uri = $this->url;
-               $this->host = $proxyhost;
-               $this->port = $proxyport;
+        $this->proxy = $proxyhost . ':' . $proxyport;
                if ($proxyusername != '' && $proxypassword != '') {
                        $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypas
sword);
                        $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
@@ -2540,6 +2543,23 @@
          }
        }
 
+
+    /**
+     * Test if the given string starts with a header that is to be skipped.
+     * Skippable headers result from chunked transfer and proxy requests.
+     */
+    function _skipHeader(&$data) {
+        $skipHeaders = array('HTTP/1.1 100',
+                             'HTTP/1.0 200 Connection established');
+        foreach ($skipHeaders as $hd) {
+            $prefix = substr($data, 0, strlen($hd));
+            if ($prefix == $hd) return true;
+        }
+
+        return false;
+    }
+
+
        function getResponse(){
                $this->incoming_payload = '';
           
@@ -2732,12 +2752,12 @@
                $this->debug('No cURL error, closing cURL');
                curl_close($this->ch);
               
-               // remove 100 header(s)
-               while (ereg('^HTTP/1.1 100',$data)) {
+               // remove 100 header(s), 200 Connection established
+               while ($this->_skipHeader($data)) {
                        if ($pos = strpos($data,"\r\n\r\n")) {
-                               $data = ltrim(substr($data,$pos));
+                               $data = substr($data, $pos + 4);
                        } elseif($pos = strpos($data,"\n\n") ) {
-                               $data = ltrim(substr($data,$pos));
+                               $data = substr($data, $pos + 2);
                        }
                }
               
@@ -4003,12 +4023,12 @@
                        $SERVER_NAME = $_SERVER['SERVER_NAME'];
                        $SERVER_PORT = $_SERVER['SERVER_PORT'];
                        $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
-                       $HTTPS = $_SERVER['HTTPS'];
+                       $HTTPS = @$_SERVER['HTTPS'];
                } elseif (isset($HTTP_SERVER_VARS)) {
                        $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
                        $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
                        $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VA
RS['SCRIPT_NAME'];
-                       $HTTPS = $HTTP_SERVER_VARS['HTTPS'];
+                       $HTTPS = @$HTTP_SERVER_VARS['HTTPS'];
                } else {
                        $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
                }
@@ -7238,4 +7258,16 @@
                return true;
        }
 }
+
+/*
+ * Dear Emacs,
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  indent-tabs-mode: nil
+ * End:
+ *
+ */
+
 ?>
View user's profileFind all posts by raimiSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
thanks for the patch!
I think it would be fine to have it there http://sourceforge.net/tracker/?group_id=57663&atid=484967
and link to the project where it's appropriate to grab the latest CVS snapshot from:
http://sourceforge.net/projects/nusoap/

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website


Joined: 22 Aug 2007
Posts: 2
Reply with quote
Hi, how do I apply this patch in nusoap.php? Please help I am new to this technology. Thanks.
View user's profileFind all posts by developerSend private message


Joined: 22 Aug 2007
Posts: 2
Reply with quote
I tried applying this patch in my nusoap.php file but still got the same error of No cURL error, closing cURL
Sad
View user's profileFind all posts by developerSend private message
SSL + HTTP Proxy does not work
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic