Skip to content

Commit 3d65d6d

Browse files
committed
Fixed bug #37799 (ftp_ssl_connect() falls back to non-ssl connection)
1 parent dc9e17f commit 3d65d6d

File tree

4 files changed

+67
-42
lines changed

4 files changed

+67
-42
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ PHP NEWS
1616
- Fixed bug #40410 (ext/posix does not compile on MacOS 10.3.9). (Tony)
1717
- Fixed bug #40109 (iptcembed fails on non-jfif jpegs). (Tony)
1818
- Fixed bug #39836 (SplObjectStorage empty after unserialize). (Marcus)
19+
- Fixed bug #37799 (ftp_ssl_connect() falls back to non-ssl connection). (Nuno)
1920

2021
08 Feb 2007, PHP 5.2.1
2122
- Added read-timeout context option "timeout" for HTTP streams. (Hannes, Ilia).

ext/ftp/ftp.c

+37-40
Original file line numberDiff line numberDiff line change
@@ -266,60 +266,57 @@ ftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC)
266266
}
267267

268268
if (ftp->resp != 334) {
269-
ftp->use_ssl = 0;
269+
return 0;
270270
} else {
271271
ftp->old_ssl = 1;
272272
ftp->use_ssl_for_data = 1;
273273
}
274274
}
275275

276-
/* now enable ssl if we still need to */
277-
if (ftp->use_ssl) {
278-
ctx = SSL_CTX_new(SSLv23_client_method());
279-
if (ctx == NULL) {
280-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL context");
276+
ctx = SSL_CTX_new(SSLv23_client_method());
277+
if (ctx == NULL) {
278+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL context");
279+
return 0;
280+
}
281+
282+
SSL_CTX_set_options(ctx, SSL_OP_ALL);
283+
284+
ftp->ssl_handle = SSL_new(ctx);
285+
if (ftp->ssl_handle == NULL) {
286+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL handle");
287+
SSL_CTX_free(ctx);
288+
return 0;
289+
}
290+
291+
SSL_set_fd(ftp->ssl_handle, ftp->fd);
292+
293+
if (SSL_connect(ftp->ssl_handle) <= 0) {
294+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS handshake failed");
295+
SSL_shutdown(ftp->ssl_handle);
296+
return 0;
297+
}
298+
299+
ftp->ssl_active = 1;
300+
301+
if (!ftp->old_ssl) {
302+
303+
/* set protection buffersize to zero */
304+
if (!ftp_putcmd(ftp, "PBSZ", "0")) {
305+
return 0;
306+
}
307+
if (!ftp_getresp(ftp)) {
281308
return 0;
282309
}
283310

284-
SSL_CTX_set_options(ctx, SSL_OP_ALL);
285-
286-
ftp->ssl_handle = SSL_new(ctx);
287-
if (ftp->ssl_handle == NULL) {
288-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create the SSL handle");
289-
SSL_CTX_free(ctx);
311+
/* enable data conn encryption */
312+
if (!ftp_putcmd(ftp, "PROT", "P")) {
290313
return 0;
291314
}
292-
293-
SSL_set_fd(ftp->ssl_handle, ftp->fd);
294-
295-
if (SSL_connect(ftp->ssl_handle) <= 0) {
296-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS handshake failed");
297-
SSL_shutdown(ftp->ssl_handle);
315+
if (!ftp_getresp(ftp)) {
298316
return 0;
299317
}
300318

301-
ftp->ssl_active = 1;
302-
303-
if (!ftp->old_ssl) {
304-
305-
/* set protection buffersize to zero */
306-
if (!ftp_putcmd(ftp, "PBSZ", "0")) {
307-
return 0;
308-
}
309-
if (!ftp_getresp(ftp)) {
310-
return 0;
311-
}
312-
313-
/* enable data conn encryption */
314-
if (!ftp_putcmd(ftp, "PROT", "P")) {
315-
return 0;
316-
}
317-
if (!ftp_getresp(ftp)) {
318-
return 0;
319-
}
320-
321-
ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
322-
}
319+
ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
323320
}
324321
}
325322
#endif

ext/ftp/tests/bug37799.phpt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Bug #37799: ftp_ssl_connect() falls back to non-ssl connection
3+
--SKIPIF--
4+
<?php
5+
require 'skipif.inc';
6+
?>
7+
--FILE--
8+
<?php
9+
$bug37799=$ssl=1;
10+
require 'server.inc';
11+
12+
$ftp = ftp_ssl_connect('127.0.0.1', $port);
13+
if (!$ftp) die("Couldn't connect to the server");
14+
15+
var_dump(ftp_login($ftp, 'user', 'pass'));
16+
17+
ftp_close($ftp);
18+
?>
19+
--EXPECTF--
20+
Warning: ftp_login(): bogus msg in %sbug37799.php on line 8
21+
bool(false)

ext/ftp/tests/server.inc

+8-2
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,21 @@ $buf = fread($s, 2048);
5959

6060

6161
function user_auth($buf) {
62-
global $user, $s, $ssl;
62+
global $user, $s, $ssl, $bug37799;
6363

6464
if (!empty($ssl)) {
6565
if ($buf !== "AUTH TLS\r\n") {
6666
fputs($s, "500 Syntax error, command unrecognized.\r\n");
6767
dump_and_exit($buf);
6868
}
6969

70-
fputs($s, "234 auth type accepted\r\n");
70+
if (empty($bug37799)) {
71+
fputs($s, "234 auth type accepted\r\n");
72+
} else {
73+
fputs($s, "666 dummy\r\n");
74+
fputs($s, "666 bogus msg\r\n");
75+
exit;
76+
}
7177

7278
if (!stream_socket_enable_crypto($s, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER)) {
7379
die("SSLv23 handshake failed.\n");

0 commit comments

Comments
 (0)