php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36103 ftp ssl connection fails during login
Submitted: 2006-01-20 15:32 UTC Modified: 2012-12-11 16:00 UTC
Votes:26
Avg. Score:4.4 ± 1.1
Reproduced:22 of 23 (95.7%)
Same Version:7 (31.8%)
Same OS:4 (18.2%)
From: rebe at unit01 dot net Assigned: tony2001 (profile)
Status: No Feedback Package: FTP related
PHP Version: 5.1.2 OS: linux
Private report: No CVE-ID: None
 [2006-01-20 15:32 UTC] rebe at unit01 dot net
Description:
------------
Ftp ssl/tls connection fails after login function. I checked on ftp client program supporting ssl (lftp) and everything works fine there. Server is linux Proftpd 1.3.0

Reproduce code:
---------------
$conn_id = ftp_ssl_connect('192.168.10.120');
$lr = ftp_login($conn_id,'login','pass');
if ($lr) {
echo ftp_pwd($conn_id)."\n";
} else {
echo "login failed\n";
}
ftp_close($conn_id);


Expected result:
----------------
/

Actual result:
--------------
Warning: ftp_login(): SSL/TLS handshake failed in /test.php on line 8

Warning: ftp_login(): AUTH TLS successful in /test.php on line 8

login failed


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-01-20 15:58 UTC] sniper@php.net
You need to figure out why you get this first: "SSL/TLS handshake failed". Most likely badly configured system.

 [2006-01-20 16:08 UTC] rebe at unit01 dot net
OK I said ftp server is configured OK, and I checked connection using lftp client program.

So it is required to configure something special on php side to get this working? PHP is compiled with ftp and openssl support ofcoz.
 [2006-01-20 16:38 UTC] sniper@php.net
Test as the user as you run your webserver with.
Or try with PHP CLI.
 [2006-01-20 16:52 UTC] rebe at unit01 dot net
It is an CLI script running as root user:

debian:/var/www/test# ./ftptls.php

Warning: ftp_login(): SSL/TLS handshake failed in /var/www/test/ftptls.php on line 4

Warning: ftp_login(): AUTH TLS successful in /var/www/test/ftptls.php on line 4
login failed

now lftp connection:
debian:/var/www/test# lftp
lftp :~> open 192.168.10.120
lftp 192.168.10.120:~> login admin qwerty
lftp admin@192.168.10.120:~> pwd
ftp://admin:qwerty@192.168.10.120
lftp admin@192.168.10.120:~> ls
drwxrwxr-x  35 ftp      ftp          4096 Jan 16 16:22 .
drwxrwxr-x  35 ftp      ftp          4096 Jan 16 16:22 ..
lftp admin@192.168.10.120:/>

Server (proftpd on second machine) is configured with options:
TLSRSACertificateFile /etc/embedos/ftp/ftpserver.cert.cert
TLSRSACertificateKeyFile /etc/embedos/ftp/ftpserver.cert.key
TLSVerifyClient off
TLSEngine on
TLSProtocol TLSv1
TLSRequired on

SSL is required. TO test it i did ftp'ing with non-ssl client:
debian:/var/www/test# ftp 192.168.10.120
Connected to 192.168.10.120.
220 Ethernus FTP Server
Name (192.168.10.120:root): admin
550 SSL/TLS required on the control channel
Login failed.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
 [2006-01-20 16:54 UTC] tony2001@php.net
Which linux is it?
 [2006-01-20 17:07 UTC] rebe at unit01 dot net
debian:/var/www/test# uname -a
Linux debian 2.6.8-1-686 #1 Thu Nov 25 04:34:30 UTC 2004 i686 GNU/Linux
 [2006-01-20 17:18 UTC] tony2001@php.net
AFAIR Debian had some problems with Openssl packages.
Try to build the newest openssl from sources and recompile PHP using it.
 [2006-01-23 10:10 UTC] rebe at unit01 dot net
OK. I did that test from Trustix distro. The same piece of code acts exactly the same way. 

For me it looks like that openssl works fine as long as many other aplications using it successfuly (apache, ftp, openvpn etc.).
 [2006-01-24 00:38 UTC] rebe at unit01 dot net
OK here's what we figured out with a friend of mine. Login function in ext/ftp.c treat all errors (also "want_more..."  ) as login fail but it is not true. A patch below is fixing problem and makes everything working fine:

@@ -243,6 +243,7 @@
 {
 #if HAVE_OPENSSL_EXT
        SSL_CTX *ctx = NULL;
+       int err,errs;
 #endif
        if (ftp == NULL) {
                return 0;
@@ -291,13 +292,24 @@
                        }

                        SSL_set_fd(ftp->ssl_handle, ftp->fd);
-
+/*
                        if (SSL_connect(ftp->ssl_handle) <= 0) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS handshake failed");
                                SSL_shutdown(ftp->ssl_handle);
                                return 0;
                        }
-
+*/
+err=SSL_connect(ftp->ssl_handle);
+while (err <= 0) {
+    errs = SSL_get_error(ftp->fd, err);
+    if ((errs != SSL_ERROR_WANT_READ) && (errs != SSL_ERROR_WANT_WRITE) && (errs != SSL_ERROR_WANT_X509_LOOKUP)) {
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS handshake failed");
+       SSL_shutdown(ftp->ssl_handle);
+       return 0;
+    }
+    err = SSL_connect(ftp->ssl_handle);
+}
+
 [2006-01-24 01:14 UTC] tony2001@php.net
Please try this patch:
http://tony2001.phpclub.net/dev/tmp/bug36103.diff

 [2006-01-24 10:44 UTC] rebe at unit01 dot net
Frankly - your patch is doing 99% percent the same thing but is not fixing problem :) I checked that twice cause I didn't believe it but still getting "handshake failed". The only difference I see is :

}while(errcode == 0 && !SSL_is_init_finished(ftp-ssl_handle));
                        ^^^^^^^^^^^^^^
we didn't use that in our fix.
 [2006-01-24 10:50 UTC] tony2001@php.net
>Frankly - your patch is doing 99% percent the same thing
Yes, it does.

>}while(errcode == 0 && !SSL_is_init_finished(ftp-ssl_handle));
>we didn't use that in our fix.
So does it work without that check?
 [2006-01-27 22:03 UTC] rebe at unit01 dot net
OK, so looks like your patch is also working properly. Just give me a couple of days - maybe 'till the middle of the next week to check everything again because I am a little bit busy now doing different work. 

I want to really confirm that this is a final sollution, so you could apply that patch into official PHP release.

It is my first subbmission and I am glad to have really active and collaborating PHP development team :)
 [2006-01-30 08:52 UTC] tony2001@php.net
>OK, so looks like your patch is also working properly.
Sorry, I didn't get that.
Does my patch work without any modifications?
 [2006-02-22 01:51 UTC] rebe at unit01 dot net
OK, so while i am little but less busy i checked everything again and it looks like both of patches solving problem while connecting to some ftp servers but not everywhere. I am not very clever with that network knowledge but i guess it is still something about blocking/nonblocking sockets.

Whole mess i produced before, that one patch is working and second not was about different ftp servers i checked.

Now i have my own ftp server configured and TLS is required on it connect. I checked again with lftp client and it's working.

Started again from scratch to compile PHP 5.1.2 
(./configure --with-apxs --enable-ftp --enable-pcntl --with-mysql --enable-sockets --with-openssl)

With Tony's patch and got that:
----------------------------------------------
Warning: ftp_login(): SSL/TLS handshake failed in /root/ftptest.php on line 5

Warning: ftp_login(): AUTH TLS successful in /root/ftptest.php on line 5
login failed 
----------------------------------------------


With my patch:
----------------------------------------------
Segmentation fault
----------------------------------------------

So, if i can help anyhow to give you more info (i.e. strace or something) let me know. I still really need to get this work.
 [2006-11-14 02:41 UTC] be_nice_or_feel_hell at yahoo dot com
Hi, If any of you can help me I would greatly appreciate it. I'm trying to get into this thru FTP and am getting the error for 550 SSL/TLS required on the control channel in CMD. As I am trying to connect though I know it is a unix apache server. I am a "noob". Can anyone help me get to this server with authentication please?
128.6.68.133
 [2007-10-12 04:36 UTC] contact dot removethis at deciacco dot com
I've found that you also have to update the ftp_getdata() function in the same ftp.c file. I was able to get my version running with tony2001's patch. You have to modify it slightly for the ftp_getdata() function. Basically, you have to use data->ssl_handle in the place of ftp->ssl_handle. For more details see my post: http://www.deciacco.com/blog/archives/124
 [2007-10-12 14:21 UTC] contact dot removethis at deciacco dot com
I made a mistake in my last comment above. It's not the ftp_getdata() function! It's the data_accept() function that also needs to be updated.
 [2008-07-21 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2012-12-11 15:15 UTC] erez dot h at zend dot com
we still have this issue on windows php build 5.3.19 and 5.4.9 so we implemented 
this patch which solve the issue. please see if you can add to future versions.

diff -ruN php-5.3.19.orig/ext/ftp/ftp.c php-5.3.19/ext/ftp/ftp.c
--- php-5.3.19.orig/ext/ftp/ftp.c	2012-11-21 22:07:23.000000000 +0200
+++ php-5.3.19/ext/ftp/ftp.c	2012-12-11 16:49:21.359682714 +0200
@@ -241,6 +241,7 @@
 int
 ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
 {
+	int errcode;
 #if HAVE_OPENSSL_EXT
 	SSL_CTX	*ctx = NULL;
 #endif
@@ -289,13 +290,27 @@
 		}
 
 		SSL_set_fd(ftp->ssl_handle, ftp->fd);
-
-		if (SSL_connect(ftp->ssl_handle) <= 0) {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS 
handshake failed");
-			SSL_shutdown(ftp->ssl_handle);
-			return 0;
-		}
-
+		
+			do {
+				errcode = SSL_connect(ftp->ssl_handle);
+				switch (SSL_get_error (ftp->ssl_handle, 
errcode)) {
+					case SSL_ERROR_NONE:
+						errcode = 1;
+						break;
+					case SSL_ERROR_WANT_WRITE:
+					case SSL_ERROR_WANT_READ:
+					case SSL_ERROR_WANT_X509_LOOKUP:
+						errcode = 0;
+						break;
+					default:
+						/* true error happened */
+						php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "SSL/TLS handshake failed");
+						SSL_shutdown(ftp->ssl_handle);
+						return 0;
+						break;
+				}
+			} while(errcode == 0 && !SSL_is_init_finished(ftp-
>ssl_handle));
+				
 		ftp->ssl_active = 1;
 
 		if (!ftp->old_ssl) {
@@ -1493,6 +1508,7 @@
 	php_sockaddr_storage addr;
 	socklen_t			size;
 
+	int errcode;
 #if HAVE_OPENSSL_EXT
 	SSL_CTX		*ctx;
 #endif
@@ -1537,11 +1553,26 @@
 			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
 		}
 			
-		if (SSL_connect(data->ssl_handle) <= 0) {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"data_accept: SSL/TLS handshake failed");
-			SSL_shutdown(data->ssl_handle);
-			return 0;
-		}
+	
+		do {
+			errcode = SSL_connect(data->ssl_handle);
+			switch (SSL_get_error (data->ssl_handle, errcode)) {
+				case SSL_ERROR_NONE:
+					errcode = 1;
+					break;
+				case SSL_ERROR_WANT_WRITE:
+				case SSL_ERROR_WANT_READ:
+				case SSL_ERROR_WANT_X509_LOOKUP:
+					errcode = 0;
+					break;
+				default:
+					/* true error happened */
+					php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "data_accept: SSL/TLS handshake failed");
+					SSL_shutdown(data->ssl_handle);
+					return 0;
+					break;
+			}
+		} while(errcode == 0 && !SSL_is_init_finished(data-
>ssl_handle));
 			
 		data->ssl_active = 1;
 	}
 [2012-12-11 16:00 UTC] tony2001@php.net
@erez dot h at zend dot com
I guess it would be better to create a new bug report and add an up to date 
reproduce case while you're at it.
Adding some more explanations to the patch would be a good idea, too.

You can also go an other way and send your patch directly to Dmitry for review, 
dmitry@zend.com/dmitry@php.net I mean.
 [2012-12-12 08:01 UTC] erez dot h at zend dot com
Hi Tony

I think this is the right place to write the comments since i am experiencing 
all the of the same issues as mentioned on comment  [2006-01-20 15:32 UTC] rebe 
at unit01 dot net.
The main difference is that it appear on our windows php and not linux.
Also need to mention the patch is used from comments
1.  [2006-01-24 00:38 UTC] rebe at unit01 dot net
2.  [2007-10-12 14:21 UTC] contact dot removethis at deciacco dot com

The test case is as follows: (http://php.net/manual/en/function.ftp-ssl-
connect.php)
<?php

// set up basic ssl connection
$conn_id = ftp_ssl_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

echo ftp_pwd($conn_id); // /

// close the ssl connection
ftp_close($conn_id);
?>

And I will pass this to Dimitry as well.
Thanks
 [2013-06-03 15:31 UTC] hessemanj2100 at gmail dot com
Here we are at versions 5.3.25 and 5.4.15 and this bug still exists? Come on, this 
is PHP for crying out loud. The most popular scripting language on the web. Please 
implement this patch already that "erez dot h at zend dot com" made. It works 
perfectly because I tried it. Just a simple patch that decides how to handle 
certain SSL errors. It sucks having to patch ftp.c every time I want to compile 
PHP with FTP support. You (PHP development team) are seriously slacking. How hard 
can it be? Add it to the source tree already!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 17:01:32 2024 UTC