From dc75f6fb3258c7c2745270fe934b9a934baee2a1 Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Sun, 3 Aug 2014 17:32:31 +0300 Subject: [PATCH] Verify MD5 sum for FFTW download Since ExternalProject provides confusing error messages with MD5 checking enabled, add a custom download step that works as expected. When passed a local file as the URL, ExternalProject does the MD5 verification just fine, so the code now downloads the tarball in a custom step and then passes that local file to ExternalProject. This allows removing the lengthy security warning that appeared there if one was just following the quick-and-dirty installation instructions, and likely only confused novice users. While this change may not improve overall security significantly, it hopefully allows everyone to agree to remove that warning and thus improve the end-user experience. Change-Id: I9ac5a30ae5858b7a6557ccb2d981cc909457d020 --- install-guide/install-guide.md | 5 -- src/contrib/fftw/.gitattributes | 1 + src/contrib/fftw/CMakeLists.txt | 57 +++++++++++++++----- src/contrib/fftw/fftw-download.cmake.cmakein | 19 +++++++ 4 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 src/contrib/fftw/.gitattributes create mode 100644 src/contrib/fftw/fftw-download.cmake.cmakein diff --git a/install-guide/install-guide.md b/install-guide/install-guide.md index 84481d0059..211f1af223 100644 --- a/install-guide/install-guide.md +++ b/install-guide/install-guide.md @@ -223,11 +223,6 @@ recommends either `cmake -DGMX_BUILD_OWN_FFTW=ON`), or * that you build FFTW from the source code. -Note that the GROMACS-managed download of the FFTW tarball has a -slight chance of posing a security risk. If you use this option, you -will see a warning that advises how you can eliminate this risk -(before the opportunity has arisen). - If you build FFTW from source yourself, get the most recent version and follow its [installation guide](http://www.fftw.org/doc/Installation-and-Customization.html#Installation-and-Customization). diff --git a/src/contrib/fftw/.gitattributes b/src/contrib/fftw/.gitattributes new file mode 100644 index 0000000000..9e8e962088 --- /dev/null +++ b/src/contrib/fftw/.gitattributes @@ -0,0 +1 @@ +fftw-download.cmake.cmakein !filter diff --git a/src/contrib/fftw/CMakeLists.txt b/src/contrib/fftw/CMakeLists.txt index b553c40589..c7d7298952 100644 --- a/src/contrib/fftw/CMakeLists.txt +++ b/src/contrib/fftw/CMakeLists.txt @@ -68,25 +68,54 @@ endif() # Machinery for running the external project set(EXTERNAL_FFTW_VERSION 3.3.3) # cmake make eats slashes //// -> // -set(GMX_BUILD_OWN_FFTW_URL "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH "URL from where to download fftw, (use an absolute path when offline)") -mark_as_advanced(GMX_BUILD_OWN_FFTW_URL) -set(EXTERNAL_FFTW_MD5SUM 0a05ca9c7b3bfddc8278e7c40791a1c2) -set (EXTERNAL_FFTW_BUILD_TARGET fftwBuild) +set(GMX_BUILD_OWN_FFTW_URL + "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH + "URL from where to download fftw (use an absolute path when offline, adjust GMX_BUILD_OWN_FFTW_MD5 if downloading other version than ${EXTERNAL_FFTW_VERSION})") +set(GMX_BUILD_OWN_FFTW_MD5 0a05ca9c7b3bfddc8278e7c40791a1c2 CACHE STRING + "Expected MD5 hash for the file at GMX_BUILD_OWN_FFTW_URL") +mark_as_advanced(GMX_BUILD_OWN_FFTW_URL GMX_BUILD_OWN_FFTW_MD5) + +# ExternalProject at least up to CMake 3.0 prints a confusing error message if +# download fails when MD5 verification is enabled. So we manage the download +# ourselves so that MD5 sum is not verified there, and then pass a local file +# as the URL to ExternalProject. This way, ExternalProject still verifies the +# MD5 sum with a proper message if that fails. +set(url "${GMX_BUILD_OWN_FFTW_URL}") +# Determine whether we are actually downloading (this matches the conditions in +# ExternalProject). ExternalProject works as expected if passed a local file. +set(is_download TRUE) +if (IS_DIRECTORY "${url}" OR "${url}" MATCHES "^file://" OR NOT "${url}" MATCHES "^[a-z]+://") + set(is_download FALSE) +endif() +if (is_download) + # For simplicity, don't try to extract the file name from the URL, but use + # a hard-coded value. + set(remote_url "${GMX_BUILD_OWN_FFTW_URL}") + set(local_path "${CMAKE_CURRENT_BINARY_DIR}/fftw.tar.gz") + set(url ${local_path}) + # Write a script to do our own download step (mimics what ExternalProject + # would do, but without MD5 sum verification at this step). + set(download_script ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake) + configure_file(fftw-download.cmake.cmakein ${download_script} @ONLY) +endif() + +# The actual build target. +set(EXTERNAL_FFTW_BUILD_TARGET fftwBuild) include(ExternalProject) -# TODO in master branch - show this warning only on the first run -# by using gmx_check_if_changed_result from I21b791ab8e4f3 when -# that becomes available -message(WARNING "The GROMACS build will download FFTW ${EXTERNAL_FFTW_VERSION} as requested, but it will not know the file it receives is correct. If you now use\nmake\n GROMACS will build and link to FFTW anyway, but there is a possible security risk if you execute a GROMACS tool that calls this library. Instead, you can use\nmake ${EXTERNAL_FFTW_BUILD_TARGET}\n to do just the download and build of FFTW, and then run\nmd5sum src/contrib/fftw/${EXTERNAL_FFTW_BUILD_TARGET}-prefix/src/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz\nto see if it matches ${EXTERNAL_FFTW_MD5SUM}. If so, everything is OK and you should use \nmake\n to proceed with the rest of the GROMACS build. Alternatively, you could stop using GMX_BUILD_OWN_FFTW, and instead follow the GROMACS installation instructions to build FFTW yourself.") -# TODO if/when CMake fixes http://www.cmake.org/Bug/view.php?id=14330 -# (ie. at least version > 2.8.11.2), consider reverting to using an -# md5sum check to avoid needing the above warning - ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET} - URL "${GMX_BUILD_OWN_FFTW_URL}" +ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET} + URL "${url}" URL_MD5 ${GMX_BUILD_OWN_FFTW_MD5} CONFIGURE_COMMAND /configure --prefix= --libdir=/lib --disable-fortran ${GMX_BUILD_OWN_FFTW_SHARED_FLAG} ${GMX_BUILD_OWN_FFTW_OPTIMIZATION_CONFIGURATION} ${GMX_BUILD_OWN_FFTW_PREC} ${GMX_BUILD_OWN_FFTW_TARGET_HOST}) -externalproject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR) +# Add a custom step to do our own download if that is necessary. +if (is_download) + ExternalProject_add_step(${EXTERNAL_FFTW_BUILD_TARGET} pre-download + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake + DEPENDERS download) +endif() + +ExternalProject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR) string(TOUPPER "${FFTW}" UPPERFFTW) string(TOLOWER "${FFTW}" LOWERFFTW) diff --git a/src/contrib/fftw/fftw-download.cmake.cmakein b/src/contrib/fftw/fftw-download.cmake.cmakein new file mode 100644 index 0000000000..777fe3b100 --- /dev/null +++ b/src/contrib/fftw/fftw-download.cmake.cmakein @@ -0,0 +1,19 @@ +# Custom download script for Gromacs external FFTW build. + +# Mimics a similar script generated by CMake ExternalProject package, but +# does not verify the MD5 sum (which would give confusing error messages if the +# download fails). +message(STATUS "downloading... + src='@remote_url@' + dest='@local_path@'") +file(DOWNLOAD "@remote_url@" "@local_path@" + SHOW_PROGRESS STATUS status LOG log) +list(GET status 0 status_code) +list(GET status 1 status_string) +if (NOT status_code EQUAL 0) + message(FATAL_ERROR "error: downloading '@remote_url@' failed + status_code: ${status_code} + status_string: ${status_string} + log: ${log}") +endif() +message(STATUS "downloading... done") -- 2.22.0