]> granicus.if.org Git - php/commitdiff
- MFB: - disable file:// when safe_mode or open_basedir are enabled
authorPierre Joye <pajoye@php.net>
Mon, 18 May 2009 10:31:08 +0000 (10:31 +0000)
committerPierre Joye <pajoye@php.net>
Mon, 18 May 2009 10:31:08 +0000 (10:31 +0000)
ext/curl/config.m4
ext/curl/interface.c

index 55e59976125075e3c41a5e8d06261194f59cdb8b..30531cfdb7261d4270c9e718298fb9b96352c94b 100644 (file)
@@ -10,6 +10,7 @@ PHP_ARG_WITH(curlwrappers, if we should use cURL for url streams,
 [  --with-curlwrappers     Use cURL for url streams], no, no)
 
 if test "$PHP_CURL" != "no"; then
+  AC_MSG_CHECKING($PHP_CURL ..........................)
   if test -r $PHP_CURL/include/curl/easy.h; then
     CURL_DIR=$PHP_CURL
   else
index 3d2b0b0531e08f0c5c829a2f61bca863a4273b4b..d69809b2d464ae898a96a7dbd4831e74879fff93 100644 (file)
@@ -147,6 +147,7 @@ static struct gcry_thread_cbs php_curl_gnutls_tsl = {
 #endif
 /* }}} */
 
+static void _php_curl_close_ex(php_curl *ch TSRMLS_DC);
 static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
 
 #define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
@@ -162,31 +163,44 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
  #define php_curl_ret(__ret) RETVAL_FALSE; return;
 #endif
 
-#define PHP_CURL_CHECK_OPEN_BASEDIR(str, len, __ret)                                                                                                   \
-       if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) &&                                                \
-           strncasecmp(str, "file:", sizeof("file:") - 1) == 0)                                                                \
-       {                                                                                                                                                                                       \
-               php_url *tmp_url;                                                                                                                                               \
-                                                                                                                       \
-               if (!(tmp_url = php_url_parse_ex(str, len))) {                                                                                  \
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL '%s'", str);                           \
-                       php_curl_ret(__ret);                                                                                    \
-               }                                                                                                       \
-                                                                                                                       \
-               if (tmp_url->host || !php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) {                              \
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL '%s' contains unencoded control characters", str);     \
-                       php_url_free(tmp_url);                                                                                                                          \
-                       php_curl_ret(__ret);                                                                                    \
-               }                                                                                                       \
-                                                                                                                                                                                               \
-               if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) ||                                                                   \
-                       (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM))       \
-               ) {                                                                                                                                                                     \
-                       php_url_free(tmp_url);                                                                                                                          \
-                       php_curl_ret(__ret);                                                                                    \
-               }                                                                                                                                                                               \
-               php_url_free(tmp_url);                                                                                                                                  \
+static int php_curl_option_url(php_curl *ch, const char *url, const int len) {
+       CURLcode     error=CURLE_OK;
+#if LIBCURL_VERSION_NUM < 0x071100
+       char *copystr = NULL;
+#endif
+       TSRMLS_FETCH();
+
+       /* Disable file:// if open_basedir or safe_mode are used */
+       if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
+#if LIBCURL_VERSION_NUM >= 0x071304
+               error = curl_easy_setopt(ch->cp, CURLOPT_PROTOCOLS, CURLPROTO_ALL & ~CURLPROTO_FILE);
+#else
+               php_url *uri;
+
+               if (!(uri = php_url_parse_ex(url, len))) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL '%s'", url);
+                       return 0;
+               }
+
+               if (!strncasecmp("file", uri->scheme, sizeof("file"))) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol 'file' disabled in cURL");
+                       php_url_free(uri);
+                       return 0;
+               }
+               php_url_free(uri);
+#endif
        }
+       /* Strings passed to libcurl as 'char *' arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
+#if LIBCURL_VERSION_NUM >= 0x071100
+       error = curl_easy_setopt(ch->cp, CURLOPT_URL, url);
+#else
+       copystr = estrndup(url, len);
+       error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr);
+       zend_llist_add_element(&ch->to_free.str, &copystr);
+#endif
+
+       return (error == CURLE_OK ? 1 : 0);
+}
 
 /* {{{ arginfo */
 ZEND_BEGIN_ARG_INFO_EX(arginfo_curl_version, 0, 0, 0)
@@ -1323,10 +1337,6 @@ PHP_FUNCTION(curl_init)
                return;
        }
 
-       if (url) {
-               PHP_CURL_CHECK_OPEN_BASEDIR(url, url_len, (void) NULL);
-       }
-
        cp = curl_easy_init();
        if (!cp) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize a new cURL handle");
@@ -1362,15 +1372,10 @@ PHP_FUNCTION(curl_init)
 #endif
 
        if (url) {
-#if LIBCURL_VERSION_NUM >= 0x071100
-               curl_easy_setopt(ch->cp, CURLOPT_URL, url);
-#else
-               char *urlcopy;
-
-               urlcopy = estrndup(url, url_len);
-               curl_easy_setopt(ch->cp, CURLOPT_URL, urlcopy);
-               zend_llist_add_element(&ch->to_free.str, &urlcopy);
-#endif
+               if (!php_curl_option_url(ch, url, url_len)) {
+                       _php_curl_close_ex(ch TSRMLS_CC);
+                       RETURN_FALSE;
+               }
        }
 
        ZEND_REGISTER_RESOURCE(return_value, ch, le_curl);
@@ -1537,6 +1542,13 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
                case CURLOPT_FTP_FILEMETHOD:
 #endif
                        convert_to_long_ex(zvalue);
+#if LIBCURL_VERSION_NUM >= 0x71304
+                       if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLPROTO_FILE cannot be activated when in safe_mode or an open_basedir is set");
+                                       RETVAL_FALSE;
+                                       return 1;
+                       }
+#endif
                        error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
                        break;
                case CURLOPT_FOLLOWLOCATION:
@@ -1584,24 +1596,32 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
 #endif
 
                        convert_to_string_ex(zvalue);
-
-                       if (option == CURLOPT_URL
 #if LIBCURL_VERSION_NUM >= 0x071300
-                               || option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE
-#endif
+                       if (
+                               option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE
+
                        ) {
-                               PHP_CURL_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue), 1);
+                               if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(zvalue), "rb+", CHECKUID_CHECK_MODE_PARAM))) {
+                                       RETVAL_FALSE;
+                                       return 1;
+                               }
                        }
-
+#endif
+                       if (option == CURLOPT_URL) {
+                               if (!php_curl_option_url(ch, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue))) {
+                                       RETVAL_FALSE;
+                                       return 1;
+                               }
+                       } else {
 #if LIBCURL_VERSION_NUM >= 0x071100
-                       /* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
-                       error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue));
+                               /* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
+                               error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue));
 #else
-                       copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
-                       error = curl_easy_setopt(ch->cp, option, copystr);
-                       zend_llist_add_element(&ch->to_free.str, &copystr);
+                               copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
+                               error = curl_easy_setopt(ch->cp, option, copystr);
+                               zend_llist_add_element(&ch->to_free.str, &copystr);
 #endif
-
+                       }
                        break;
                }
                case CURLOPT_FILE:
@@ -2233,10 +2253,8 @@ PHP_FUNCTION(curl_close)
 
 /* {{{ _php_curl_close()
    List destructor for curl handles */
-static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
 {
-       php_curl *ch = (php_curl *) rsrc->ptr;
-
 #if PHP_CURL_DEBUG
        fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
 #endif
@@ -2279,6 +2297,15 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 }
 /* }}} */
 
+/* {{{ _php_curl_close()
+   List destructor for curl handles */
+static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       php_curl *ch = (php_curl *) rsrc->ptr;
+       _php_curl_close_ex(ch TSRMLS_CC);
+}
+/* }}} */
+
 #endif /* HAVE_CURL */
 
 /*