Skip to content

Commit 9f8bd82

Browse files
committed
fix(security): harden network fetches and build detection
1 parent fa7aa83 commit 9f8bd82

File tree

11 files changed

+460
-43
lines changed

11 files changed

+460
-43
lines changed

cmake/ConkyPlatformChecks.cmake

Lines changed: 264 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,50 @@ set(conky_libs ${conky_libs} ${CLOCK_GETTIME_LIB})
5656
# standard path to search for includes
5757
set(INCLUDE_SEARCH_PATH /usr/include /usr/local/include)
5858

59+
function(conky_append_include_dirs dest_var)
60+
foreach(_dir IN LISTS ARGN)
61+
if(NOT _dir)
62+
continue()
63+
endif()
64+
65+
if(OS_DARWIN)
66+
if(_dir MATCHES "/usr/include/?$")
67+
continue()
68+
endif()
69+
if(_dir MATCHES "MacOSX[^/]*/usr/include/?$")
70+
continue()
71+
endif()
72+
endif()
73+
74+
list(APPEND ${dest_var} ${_dir})
75+
endforeach()
76+
77+
list(REMOVE_DUPLICATES ${dest_var})
78+
set(${dest_var} "${${dest_var}}" PARENT_SCOPE)
79+
endfunction()
80+
81+
function(conky_filter_implicit_include_dirs var_name)
82+
set(_filtered)
83+
foreach(_dir IN LISTS ${var_name})
84+
if(OS_DARWIN AND _dir MATCHES "^/nix/store/")
85+
if(_dir MATCHES "libcxx"
86+
OR _dir MATCHES "compiler-rt"
87+
OR _dir MATCHES "clang-wrapper"
88+
OR _dir MATCHES "clang-[0-9]"
89+
OR _dir MATCHES "libobjc"
90+
OR _dir MATCHES "resource-root"
91+
OR _dir MATCHES "libSystem"
92+
OR _dir MATCHES "sdkroot")
93+
list(APPEND _filtered "${_dir}")
94+
endif()
95+
else()
96+
list(APPEND _filtered "${_dir}")
97+
endif()
98+
endforeach()
99+
100+
set(${var_name} "${_filtered}" PARENT_SCOPE)
101+
endfunction()
102+
59103
# Detect CI
60104
if(DEFINED ENV{CI})
61105
# For GitHub actions CI=true is set
@@ -122,6 +166,24 @@ else(CMAKE_SYSTEM_NAME MATCHES "Darwin")
122166
set(OS_DARWIN false)
123167
endif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
124168

169+
if(OS_DARWIN)
170+
set(CONKY_C_IMPLICIT_INCLUDE_DIRECTORIES_RAW
171+
${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
172+
set(CONKY_CXX_IMPLICIT_INCLUDE_DIRECTORIES_RAW
173+
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
174+
set(CONKY_PLATFORM_EXTRA_INCLUDE_DIRS
175+
${CONKY_C_IMPLICIT_INCLUDE_DIRECTORIES_RAW}
176+
${CONKY_CXX_IMPLICIT_INCLUDE_DIRECTORIES_RAW})
177+
list(REMOVE_DUPLICATES CONKY_PLATFORM_EXTRA_INCLUDE_DIRS)
178+
179+
# Nix clang wrappers can report third-party package headers as implicit
180+
# includes. CMake then drops those directories from generated compile
181+
# commands, so feature-enabled builds lose X11/Lua/curl headers unless we
182+
# keep only the true toolchain/runtime implicit paths here.
183+
conky_filter_implicit_include_dirs(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)
184+
conky_filter_implicit_include_dirs(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
185+
endif()
186+
125187
if(NOT OS_LINUX
126188
AND NOT OS_FREEBSD
127189
AND NOT OS_OPENBSD
@@ -185,15 +247,74 @@ if(BUILD_I18N)
185247
include(FindIntl)
186248
find_package(Intl)
187249

250+
if(OS_DARWIN AND NOT Intl_FOUND)
251+
set(CONKY_DARWIN_GETTEXT_PREFIXES
252+
/opt/homebrew/opt/gettext
253+
/usr/local/opt/gettext)
254+
255+
find_path(CONKY_DARWIN_GETTEXT_INCLUDE_DIR
256+
NAMES libintl.h
257+
PATHS ${CONKY_DARWIN_GETTEXT_PREFIXES}
258+
PATH_SUFFIXES include
259+
NO_DEFAULT_PATH)
260+
find_library(CONKY_DARWIN_GETTEXT_LIBRARY
261+
NAMES intl libintl
262+
PATHS ${CONKY_DARWIN_GETTEXT_PREFIXES}
263+
PATH_SUFFIXES lib
264+
NO_DEFAULT_PATH)
265+
266+
if(CONKY_DARWIN_GETTEXT_INCLUDE_DIR AND CONKY_DARWIN_GETTEXT_LIBRARY)
267+
set(Intl_FOUND TRUE)
268+
set(Intl_IS_BUILT_IN FALSE)
269+
set(Intl_INCLUDE_DIR "${CONKY_DARWIN_GETTEXT_INCLUDE_DIR}")
270+
set(Intl_LIBRARY "${CONKY_DARWIN_GETTEXT_LIBRARY}")
271+
set(Intl_INCLUDE_DIRS "${CONKY_DARWIN_GETTEXT_INCLUDE_DIR}")
272+
set(Intl_LIBRARIES "${CONKY_DARWIN_GETTEXT_LIBRARY}")
273+
set(Intl_INCLUDE_DIR "${CONKY_DARWIN_GETTEXT_INCLUDE_DIR}" CACHE PATH
274+
"Directory containing libintl headers" FORCE)
275+
set(Intl_LIBRARY "${CONKY_DARWIN_GETTEXT_LIBRARY}" CACHE FILEPATH
276+
"Path to libintl library" FORCE)
277+
endif()
278+
endif()
279+
188280
if(NOT Intl_FOUND)
189281
if(OS_DARWIN)
190-
message(WARNING "Try running `brew install gettext` for I18N support")
191-
# Should be present by default everywhere else
282+
message(FATAL_ERROR
283+
"Unable to find libintl.\n"
284+
"Checked CMake's default search and Homebrew prefixes:\n"
285+
" /opt/homebrew/opt/gettext\n"
286+
" /usr/local/opt/gettext\n"
287+
"If gettext is installed via Homebrew, re-run CMake after ensuring\n"
288+
"the prefix exists or pass -DIntl_INCLUDE_DIR and -DIntl_LIBRARY explicitly.")
289+
else()
290+
message(FATAL_ERROR "Unable to find libintl")
192291
endif(OS_DARWIN)
193-
message(FATAL_ERROR "Unable to find libintl")
194292
endif(NOT Intl_FOUND)
195293

196-
include_directories(${Intl_INCLUDE_DIRS})
294+
if(OS_DARWIN AND Intl_IS_BUILT_IN)
295+
set(CONKY_DARWIN_INTL_IMPLICIT_LIBS)
296+
foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}
297+
${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES})
298+
if(_lib STREQUAL "intl" OR _lib STREQUAL "iconv")
299+
unset(CONKY_IMPLICIT_LIB_PATH CACHE)
300+
find_library(CONKY_IMPLICIT_LIB_PATH
301+
NAMES ${_lib}
302+
PATHS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}
303+
${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}
304+
NO_DEFAULT_PATH)
305+
if(CONKY_IMPLICIT_LIB_PATH)
306+
list(APPEND CONKY_DARWIN_INTL_IMPLICIT_LIBS
307+
${CONKY_IMPLICIT_LIB_PATH})
308+
else()
309+
list(APPEND CONKY_DARWIN_INTL_IMPLICIT_LIBS ${_lib})
310+
endif()
311+
endif()
312+
endforeach()
313+
list(REMOVE_DUPLICATES CONKY_DARWIN_INTL_IMPLICIT_LIBS)
314+
set(conky_libs ${conky_libs} ${CONKY_DARWIN_INTL_IMPLICIT_LIBS})
315+
endif()
316+
317+
conky_append_include_dirs(conky_includes ${Intl_INCLUDE_DIRS})
197318
set(conky_libs ${conky_libs} ${Intl_LIBRARIES})
198319
endif(BUILD_I18N)
199320

@@ -253,9 +374,70 @@ if(BUILD_IPV6)
253374
endif(BUILD_IPV6)
254375

255376
if(BUILD_HTTP)
256-
pkg_check_modules(MICROHTTPD REQUIRED libmicrohttpd>=0.9.25)
257-
set(conky_libs ${conky_libs} ${MICROHTTPD_LINK_LIBRARIES})
258-
set(conky_includes ${conky_includes} ${MICROHTTPD_INCLUDE_DIRS})
377+
pkg_check_modules(MICROHTTPD libmicrohttpd>=0.9.25)
378+
379+
if(MICROHTTPD_FOUND)
380+
set(conky_libs ${conky_libs} ${MICROHTTPD_LINK_LIBRARIES})
381+
conky_append_include_dirs(conky_includes ${MICROHTTPD_INCLUDE_DIRS})
382+
else()
383+
if(OS_DARWIN)
384+
set(CONKY_DARWIN_MICROHTTPD_PREFIXES
385+
/opt/homebrew/opt/libmicrohttpd
386+
/usr/local/opt/libmicrohttpd)
387+
388+
find_path(MICROHTTPD_INCLUDE_DIR
389+
NAMES microhttpd.h
390+
PATHS ${CONKY_DARWIN_MICROHTTPD_PREFIXES}
391+
PATH_SUFFIXES include
392+
NO_DEFAULT_PATH)
393+
find_library(MICROHTTPD_LIBRARY
394+
NAMES microhttpd libmicrohttpd
395+
PATHS ${CONKY_DARWIN_MICROHTTPD_PREFIXES}
396+
PATH_SUFFIXES lib
397+
NO_DEFAULT_PATH)
398+
else()
399+
find_path(MICROHTTPD_INCLUDE_DIR NAMES microhttpd.h)
400+
find_library(MICROHTTPD_LIBRARY NAMES microhttpd libmicrohttpd)
401+
endif()
402+
403+
if(MICROHTTPD_INCLUDE_DIR AND MICROHTTPD_LIBRARY)
404+
file(STRINGS "${MICROHTTPD_INCLUDE_DIR}/microhttpd.h"
405+
MICROHTTPD_VERSION_LINE
406+
REGEX "^#define MHD_VERSION 0x[0-9A-Fa-f]+")
407+
if(NOT MICROHTTPD_VERSION_LINE)
408+
message(FATAL_ERROR
409+
"Unable to determine libmicrohttpd version from "
410+
"${MICROHTTPD_INCLUDE_DIR}/microhttpd.h")
411+
endif()
412+
413+
string(REGEX REPLACE ".*0x([0-9A-Fa-f]+).*" "\\1"
414+
MICROHTTPD_VERSION_HEX "${MICROHTTPD_VERSION_LINE}")
415+
math(EXPR MICROHTTPD_VERSION_NUM "0x${MICROHTTPD_VERSION_HEX}")
416+
math(EXPR MICROHTTPD_MIN_VERSION_NUM "0x00092500")
417+
418+
if(MICROHTTPD_VERSION_NUM LESS MICROHTTPD_MIN_VERSION_NUM)
419+
message(FATAL_ERROR
420+
"Found libmicrohttpd version 0x${MICROHTTPD_VERSION_HEX}, but "
421+
"Conky requires at least 0x00092500 (0.9.25).")
422+
endif()
423+
424+
set(MICROHTTPD_INCLUDE_DIRS "${MICROHTTPD_INCLUDE_DIR}")
425+
set(MICROHTTPD_LINK_LIBRARIES "${MICROHTTPD_LIBRARY}")
426+
set(conky_libs ${conky_libs} ${MICROHTTPD_LINK_LIBRARIES})
427+
conky_append_include_dirs(conky_includes ${MICROHTTPD_INCLUDE_DIRS})
428+
elseif(OS_DARWIN)
429+
message(FATAL_ERROR
430+
"Unable to find libmicrohttpd.\n"
431+
"Checked pkg-config and Homebrew prefixes:\n"
432+
" /opt/homebrew/opt/libmicrohttpd\n"
433+
" /usr/local/opt/libmicrohttpd\n"
434+
"If installed via Homebrew, ensure PKG_CONFIG_PATH includes\n"
435+
"libmicrohttpd/lib/pkgconfig or pass MICROHTTPD_INCLUDE_DIR and\n"
436+
"MICROHTTPD_LIBRARY explicitly.")
437+
else()
438+
message(FATAL_ERROR "Unable to find libmicrohttpd")
439+
endif()
440+
endif()
259441
endif(BUILD_HTTP)
260442

261443
if(BUILD_NCURSES)
@@ -475,6 +657,7 @@ if(BUILD_X11)
475657

476658
if(X11_xcb_errors_FOUND)
477659
set(HAVE_XCB_ERRORS true)
660+
set(conky_includes ${conky_includes} ${X11_xcb_errors_INCLUDE_PATH})
478661
set(conky_libs ${conky_libs} ${X11_xcb_LIB} ${X11_xcb_errors_LIB})
479662
else(X11_xcb_errors_FOUND)
480663
set(HAVE_XCB_ERRORS false)
@@ -649,9 +832,79 @@ if(BUILD_PULSEAUDIO)
649832
endif(BUILD_PULSEAUDIO)
650833

651834
if(WANT_CURL)
652-
pkg_check_modules(CURL REQUIRED libcurl)
653-
set(conky_libs ${conky_libs} ${CURL_LINK_LIBRARIES})
654-
set(conky_includes ${conky_includes} ${CURL_INCLUDE_DIRS})
835+
pkg_check_modules(CURL libcurl)
836+
if(CURL_FOUND)
837+
set(conky_libs ${conky_libs} ${CURL_LINK_LIBRARIES})
838+
conky_append_include_dirs(conky_includes ${CURL_INCLUDE_DIRS})
839+
else()
840+
find_package(CURL REQUIRED)
841+
set(CONKY_CURL_INCLUDE_CANDIDATE "${CURL_INCLUDE_DIRS}")
842+
if(NOT CONKY_CURL_INCLUDE_CANDIDATE)
843+
set(CONKY_CURL_INCLUDE_CANDIDATE "${CURL_INCLUDE_DIR}")
844+
endif()
845+
846+
set(CONKY_CURL_LIBRARY_CANDIDATE "${CURL_LIBRARIES}")
847+
if(NOT CONKY_CURL_LIBRARY_CANDIDATE)
848+
if(CURL_LIBRARY_RELEASE)
849+
set(CONKY_CURL_LIBRARY_CANDIDATE "${CURL_LIBRARY_RELEASE}")
850+
elseif(CURL_LIBRARY)
851+
set(CONKY_CURL_LIBRARY_CANDIDATE "${CURL_LIBRARY}")
852+
endif()
853+
endif()
854+
855+
if(OS_DARWIN AND
856+
(NOT CONKY_CURL_INCLUDE_CANDIDATE OR
857+
CONKY_CURL_INCLUDE_CANDIDATE MATCHES "MacOSX[^/]*/usr/include/?$"))
858+
set(CONKY_DARWIN_CURL_PREFIXES
859+
/opt/homebrew/opt/curl
860+
/usr/local/opt/curl)
861+
862+
find_path(CONKY_DARWIN_CURL_INCLUDE_DIR
863+
NAMES curl/curl.h
864+
PATHS ${CONKY_DARWIN_CURL_PREFIXES}
865+
PATH_SUFFIXES include
866+
NO_DEFAULT_PATH)
867+
find_library(CONKY_DARWIN_CURL_LIBRARY
868+
NAMES curl libcurl
869+
PATHS ${CONKY_DARWIN_CURL_PREFIXES}
870+
PATH_SUFFIXES lib
871+
NO_DEFAULT_PATH)
872+
873+
if(CONKY_DARWIN_CURL_INCLUDE_DIR AND CONKY_DARWIN_CURL_LIBRARY)
874+
set(CONKY_CURL_INCLUDE_CANDIDATE "${CONKY_DARWIN_CURL_INCLUDE_DIR}")
875+
set(CONKY_CURL_LIBRARY_CANDIDATE "${CONKY_DARWIN_CURL_LIBRARY}")
876+
endif()
877+
endif()
878+
879+
if(NOT CONKY_CURL_INCLUDE_CANDIDATE OR
880+
NOT EXISTS "${CONKY_CURL_INCLUDE_CANDIDATE}/curl/curl.h" OR
881+
NOT CONKY_CURL_LIBRARY_CANDIDATE)
882+
message(FATAL_ERROR
883+
"Unable to find a consistent libcurl installation.\n"
884+
"If libcurl is installed in a non-standard prefix, set PKG_CONFIG_PATH\n"
885+
"or pass -DCURL_INCLUDE_DIR and -DCURL_LIBRARY explicitly.")
886+
endif()
887+
888+
get_filename_component(CONKY_CURL_LIBRARY_DIR
889+
"${CONKY_CURL_LIBRARY_CANDIDATE}" DIRECTORY)
890+
get_filename_component(CONKY_CURL_PREFIX
891+
"${CONKY_CURL_INCLUDE_CANDIDATE}" DIRECTORY)
892+
get_filename_component(CONKY_CURL_PREFIX
893+
"${CONKY_CURL_PREFIX}" DIRECTORY)
894+
895+
if(NOT CONKY_CURL_LIBRARY_DIR MATCHES "^${CONKY_CURL_PREFIX}(/|$)")
896+
message(FATAL_ERROR
897+
"Detected libcurl headers in '${CONKY_CURL_INCLUDE_CANDIDATE}' but "
898+
"library in '${CONKY_CURL_LIBRARY_CANDIDATE}'.\n"
899+
"Refusing to mix libcurl installations; set PKG_CONFIG_PATH or pass "
900+
"-DCURL_INCLUDE_DIR and -DCURL_LIBRARY explicitly.")
901+
endif()
902+
903+
set(CURL_INCLUDE_DIRS "${CONKY_CURL_INCLUDE_CANDIDATE}")
904+
set(CURL_LIBRARIES "${CONKY_CURL_LIBRARY_CANDIDATE}")
905+
set(conky_libs ${conky_libs} ${CURL_LIBRARIES})
906+
conky_append_include_dirs(conky_includes ${CURL_INCLUDE_DIRS})
907+
endif()
655908
endif(WANT_CURL)
656909

657910
# Common libraries
@@ -661,12 +914,6 @@ if(WANT_GLIB)
661914
set(conky_includes ${conky_includes} ${GLIB_INCLUDE_DIRS})
662915
endif(WANT_GLIB)
663916

664-
if(WANT_CURL)
665-
pkg_check_modules(CURL REQUIRED libcurl)
666-
set(conky_libs ${conky_libs} ${CURL_LINK_LIBRARIES})
667-
set(conky_includes ${conky_includes} ${CURL_INCLUDE_DIRS})
668-
endif(WANT_CURL)
669-
670917
if(WANT_LIBXML2)
671918
include(FindLibXml2)
672919

@@ -675,7 +922,7 @@ if(WANT_LIBXML2)
675922
endif(NOT LIBXML2_FOUND)
676923

677924
set(conky_libs ${conky_libs} ${LIBXML2_LIBRARIES})
678-
set(conky_includes ${conky_includes} ${LIBXML2_INCLUDE_DIR})
925+
conky_append_include_dirs(conky_includes ${LIBXML2_INCLUDE_DIR})
679926
endif(WANT_LIBXML2)
680927

681928
# Look for doc generation programs

0 commit comments

Comments
 (0)