From ec4a3fa68e19346e7317360633b0000d038ef42a Mon Sep 17 00:00:00 2001 From: Stefan Esser Date: Sun, 8 Sep 2002 16:45:32 +0000 Subject: [PATCH] Added EXPERIMENTAL ftps fopen wrapper. For now this leaks the control connection stream because you cannot close the control connection in ssl mode before you read the data. --- ext/standard/basic_functions.c | 1 + ext/standard/ftp_fopen_wrapper.c | 94 ++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 12 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 0be12d3935..5da652f1c0 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1027,6 +1027,7 @@ PHP_MINIT_FUNCTION(basic) php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC); # if HAVE_OPENSSL_EXT php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC); + php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC); # endif #endif diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 003fd1e65c..e4d44bf8ee 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -83,11 +83,12 @@ static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer while (php_stream_gets(stream, buffer, buffer_size-1) && !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) && isdigit((int) buffer[2]) && buffer[3] == ' ')); - return strtol(buffer, NULL, 10); } #define GET_FTP_RESULT(stream) get_ftp_result((stream), tmp_line, sizeof(tmp_line) TSRMLS_CC) +#define FTPS_ENCRYPT_DATA 1 + static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb @@ -118,13 +119,13 @@ php_stream_wrapper php_stream_ftp_wrapper = { */ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { - php_stream *stream=NULL; + php_stream *stream=NULL, *datastream=NULL; php_url *resource=NULL; char tmp_line[512]; unsigned short portno; char *scratch; int result; - int i; + int i, use_ssl, use_ssl_on_data=0; char *tpath, *ttpath; size_t file_size = 0; @@ -137,6 +138,8 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch if (resource == NULL || resource->path == NULL) return NULL; + use_ssl = resource->scheme && (strlen(resource->scheme) > 3) && resource->scheme[3] == 's'; + /* use port 21 if one wasn't specified */ if (resource->port == 0) resource->port = 21; @@ -155,6 +158,62 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch goto errexit; } +#if HAVE_OPENSSL_EXT + if (use_ssl) { + + /* send the AUTH TLS request name */ + php_stream_write_string(stream, "AUTH TLS\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + if (result != 234) { + /* AUTH TLS not supported try AUTH SSL */ + php_stream_write_string(stream, "AUTH SSL\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + if (result != 334) { + use_ssl = 0; + } + } else { + /* encrypt data etc */ + + + } + + } + + if (use_ssl) { + if (use_ssl && php_stream_sock_ssl_activate_with_method(stream, 1, SSLv23_method()) == FAILURE) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); + php_stream_close(stream); + stream = NULL; + goto errexit; + } + + /* set PBSZ to 0 */ + php_stream_write_string(stream, "PBSZ 0\r\n"); + + /* ignore the response */ + result = GET_FTP_RESULT(stream); + + /* set data connection protection level */ +#if FTPS_ENCRYPT_DATA + php_stream_write_string(stream, "PROT P\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + use_ssl_on_data = result >= 200 && result<=299; +#else + php_stream_write_string(stream, "PROT C\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); +#endif + } + +#endif + /* send the user name */ php_stream_write_string(stream, "USER "); if (resource->user != NULL) { @@ -237,7 +296,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch /* set up the passive connection */ - /* We try EPSV first, needed for IPv6 and works on some IPv4 servers */ + /* We try EPSV first, needed for IPv6 and works on some IPv4 servers */ php_stream_write_string(stream, "EPSV\r\n"); result = GET_FTP_RESULT(stream); @@ -308,21 +367,32 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch } else { php_stream_write_string(stream, "/"); } - - /* close control connection */ - php_stream_write_string(stream, "\r\nQUIT\r\n"); - php_stream_close(stream); + php_stream_write_string(stream, "\r\n"); + + /* close control connection if not in ssl mode */ + if (!use_ssl) { + php_stream_write_string(stream, "QUIT\r\n"); + php_stream_close(stream); + } /* open the data channel */ - stream = php_stream_sock_open_host(resource->host, portno, SOCK_STREAM, 0, 0); - if (stream == NULL) + datastream = php_stream_sock_open_host(resource->host, portno, SOCK_STREAM, 0, 0); + if (datastream == NULL) goto errexit; - php_stream_context_set(stream, context); + php_stream_context_set(datastream, context); php_stream_notify_progress_init(context, 0, file_size); + if (use_ssl_on_data && php_stream_sock_ssl_activate_with_method(datastream, 1, SSLv23_method()) == FAILURE) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); + php_stream_close(datastream); + datastream = NULL; + goto errexit; + } + + php_url_free(resource); - return stream; + return datastream; errexit: php_url_free(resource); -- 2.40.0