diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-12-23 23:12:26 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-12-23 23:54:34 +0100 |
| commit | 0a1f1fe469029ae31591dc8b51d20f5617496128 (patch) | |
| tree | 16e6df2287ea8394912ce89fbab793d74a77f34e | |
| parent | 9d0bd793b552e248a10f9ff8b6c62d942fe437a1 (diff) | |
| download | PROJ-0a1f1fe469029ae31591dc8b51d20f5617496128.tar.gz PROJ-0a1f1fe469029ae31591dc8b51d20f5617496128.zip | |
Network: only enable it if PROJ_NETWORK=ON or proj_context_set_enable_network(ctx, true)
| -rw-r--r-- | scripts/reference_exported_symbols.txt | 1 | ||||
| -rw-r--r-- | src/filemanager.cpp | 58 | ||||
| -rw-r--r-- | src/proj.h | 3 | ||||
| -rw-r--r-- | src/proj_internal.h | 4 | ||||
| -rw-r--r-- | test/unit/test_network.cpp | 49 |
5 files changed, 108 insertions, 7 deletions
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt index 6e4e5302..9d7d400a 100644 --- a/scripts/reference_exported_symbols.txt +++ b/scripts/reference_exported_symbols.txt @@ -794,6 +794,7 @@ proj_context_get_use_proj4_init_rules proj_context_guess_wkt_dialect proj_context_set_autoclose_database proj_context_set_database_path +proj_context_set_enable_network proj_context_set_file_finder proj_context_set_network_callbacks proj_context_set(PJconsts*, projCtx_t*) diff --git a/src/filemanager.cpp b/src/filemanager.cpp index ea0a63ea..cd738d5e 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -63,9 +63,9 @@ class MyMutex { //! @cond Doxygen_Suppress -NS_PROJ_START +using namespace NS_PROJ::internal; -using namespace internal; +NS_PROJ_START // --------------------------------------------------------------------------- @@ -488,6 +488,14 @@ std::unique_ptr<File> FileManager::open(PJ_CONTEXT *ctx, const char *filename) { } #endif if (starts_with(filename, "http://") || starts_with(filename, "https://")) { + if (!pj_context_is_network_enabled(ctx)) { + pj_log( + ctx, PJ_LOG_ERROR, + "Attempt at accessing remote resource not authorized. Either " + "set PROJ_NETWORK=ON or " + "proj_context_set_enable_network(ctx, TRUE)"); + return nullptr; + } return NetworkFile::open(ctx, filename); } return FileStdio::open(ctx, filename); @@ -756,3 +764,49 @@ int proj_context_set_network_callbacks( ctx->networking.user_data = user_data; return true; } + +// --------------------------------------------------------------------------- + +/** Enable or disable network access. +* +* @param ctx PROJ context, or NULL +* @param enable TRUE if network access is allowed. +* @return TRUE if network access is possible. That is either libcurl is +* available, or an alternate interface has been set. +*/ +int proj_context_set_enable_network(PJ_CONTEXT *ctx, int enable) { + if (ctx == nullptr) { + ctx = pj_get_default_ctx(); + } + ctx->networking.enabled_env_variable_checked = true; + ctx->networking.enabled = enable != FALSE; +#ifdef CURL_ENABLED + return ctx->networking.enabled; +#else + return ctx->networking.enabled && + ctx->networking.open != NS_PROJ::no_op_network_open; +#endif +} + +// --------------------------------------------------------------------------- + +//! @cond Doxygen_Suppress + +bool pj_context_is_network_enabled(PJ_CONTEXT *ctx) { + if (ctx == nullptr) { + ctx = pj_get_default_ctx(); + } + if (ctx->networking.enabled_env_variable_checked) { + return ctx->networking.enabled; + } + const char *enabled = getenv("PROJ_NETWORK"); + if (enabled && enabled[0] != '\0') { + ctx->networking.enabled = ci_equal(enabled, "ON") || + ci_equal(enabled, "YES") || + ci_equal(enabled, "TRUE"); + } + ctx->networking.enabled_env_variable_checked = true; + return ctx->networking.enabled; +} + +//! @endcond @@ -421,6 +421,9 @@ int PROJ_DLL proj_context_set_network_callbacks( proj_network_get_last_error_type get_last_error_cbk, void* user_data); +int PROJ_DLL proj_context_set_enable_network(PJ_CONTEXT* ctx, + int enabled); + /*! @cond Doxygen_Suppress */ /* Manage the transformation definition object PJ */ diff --git a/src/proj_internal.h b/src/proj_internal.h index 0c148d02..d54d8fb9 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -668,6 +668,8 @@ struct projCppContext; struct projNetworkCallbacksAndData { + bool enabled = false; + bool enabled_env_variable_checked = false; // whereas we have checked PROJ_NETWORK env variable proj_network_open_cbk_type open = nullptr; proj_network_close_cbk_type close = nullptr; proj_network_get_header_value_cbk_type get_header_value = nullptr; @@ -824,6 +826,8 @@ PJ *pj_create_argv_internal (PJ_CONTEXT *ctx, int argc, char **argv); void pj_pipeline_assign_context_to_steps( PJ* P, PJ_CONTEXT* ctx ); +bool pj_context_is_network_enabled(PJ_CONTEXT* ctx); + /* classic public API */ #include "proj_api.h" diff --git a/test/unit/test_network.cpp b/test/unit/test_network.cpp index 5940814b..ba592da4 100644 --- a/test/unit/test_network.cpp +++ b/test/unit/test_network.cpp @@ -30,6 +30,7 @@ #include <memory> #include <stdio.h> +#include <stdlib.h> #include "proj_internal.h" #include <proj.h> @@ -77,18 +78,54 @@ TEST(networking, initial_check) { // --------------------------------------------------------------------------- +static void silent_logger(void *, int, const char *) {} + +// --------------------------------------------------------------------------- + TEST(networking, basic) { - auto P = proj_create( - PJ_DEFAULT_CTX, + const char *pipeline = "+proj=pipeline " "+step +proj=unitconvert +xy_in=deg +xy_out=rad " "+step +proj=hgridshift +grids=https://cdn.proj.org/ntf_r93.tif " - "+step +proj=unitconvert +xy_in=rad +xy_out=deg "); + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"; + + // network access disabled by default + auto ctx = proj_context_create(); + proj_log_func(ctx, nullptr, silent_logger); + auto P = proj_create(ctx, pipeline); + ASSERT_EQ(P, nullptr); + proj_context_destroy(ctx); + +#ifdef CURL_ENABLED + // enable through env variable + ctx = proj_context_create(); + putenv(const_cast<char *>("PROJ_NETWORK=ON")); + P = proj_create(ctx, pipeline); + if (networkAccessOK) { + ASSERT_NE(P, nullptr); + } + proj_destroy(P); + proj_context_destroy(ctx); + putenv(const_cast<char *>("PROJ_NETWORK=")); +#endif + + // still disabled + ctx = proj_context_create(); + proj_log_func(ctx, nullptr, silent_logger); + P = proj_create(ctx, pipeline); + ASSERT_EQ(P, nullptr); + proj_context_destroy(ctx); + + // enable through API + ctx = proj_context_create(); + proj_context_set_enable_network(ctx, true); + P = proj_create(ctx, pipeline); #ifdef CURL_ENABLED if (networkAccessOK) { ASSERT_NE(P, nullptr); } else { ASSERT_EQ(P, nullptr); + proj_context_destroy(ctx); return; } double lon = 2; @@ -102,16 +139,16 @@ TEST(networking, basic) { #else ASSERT_EQ(P, nullptr); #endif + proj_context_destroy(ctx); } // --------------------------------------------------------------------------- #ifdef CURL_ENABLED -static void silent_logger(void *, int, const char *) {} - TEST(networking, curl_invalid_resource) { auto ctx = proj_context_create(); + proj_context_set_enable_network(ctx, true); proj_log_func(ctx, nullptr, silent_logger); auto P = proj_create( ctx, "+proj=hgridshift +grids=https://i_do_not.exist/my.tif"); @@ -364,6 +401,7 @@ static const char *get_last_error_cbk(PJ_CONTEXT * /*ctx*/, TEST(networking, custom) { auto ctx = proj_context_create(); + proj_context_set_enable_network(ctx, true); ExchangeWithCallback exchange; ASSERT_TRUE(proj_context_set_network_callbacks( ctx, open_cbk, close_cbk, get_header_value_cbk, read_range_cbk, @@ -499,6 +537,7 @@ TEST(networking, custom) { TEST(networking, getfilesize) { auto ctx = proj_context_create(); + proj_context_set_enable_network(ctx, true); ExchangeWithCallback exchange; ASSERT_TRUE(proj_context_set_network_callbacks( ctx, open_cbk, close_cbk, get_header_value_cbk, read_range_cbk, |
