-
Notifications
You must be signed in to change notification settings - Fork 2.5k
CMake: make HTTPS support more generic #4283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks a lot! Will review in the near future. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice PR indeed, I definitly like what's going on here. There are some adjustments needed here, would be nice if you could make them.
Anyway, thanks for working on this!
tests/main.c
Outdated
if (res < 0) { | ||
return res; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An error message would be nice here to aid the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -10,7 +10,7 @@ | |||
#include "sysdir.h" | |||
#include "filter.h" | |||
#include "merge_driver.h" | |||
#include "openssl_stream.h" | |||
#include "streams/openssl.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just putting it at an arbitratry position: you should probably adjust the include guards of renamed header files, even though it's mostly a cosmetic change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/streams/openssl.c
Outdated
int git_openssl_set_cert_file(const char *file, const char *path) | ||
{ | ||
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) { | ||
giterr_set(GITERR_SSL, "SSL error: %s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe be a bit more specific here? E.g. "could not set default locations for certificates"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, fixed. I also tweaked some error codes where those functions are called.
src/streams/openssl.c
Outdated
@@ -627,6 +627,16 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) | |||
return error; | |||
} | |||
|
|||
int git_openssl_set_cert_file(const char *file, const char *path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually use "__" to denote private API. In this case "git_openssl__set_cert_file".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/streams/openssl.h
Outdated
@@ -13,6 +13,8 @@ extern int git_openssl_stream_global_init(void); | |||
|
|||
extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port); | |||
|
|||
extern int git_openssl_set_cert_file(const char *file, const char *path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some documentation would be nice here, even if it's private API. I certainly would be confused what "file" and "path" actually mean in this context
src/streams/openssl.c
Outdated
@@ -653,4 +663,13 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) | |||
return -1; | |||
} | |||
|
|||
int git_openssl_set_ca_location(const char *file, const char *path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you mean git_openssl_set_cert_file
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, copy-paste failure. Settled on git_openssl__set_cert_location
.
CMakeLists.txt
Outdated
@@ -293,6 +275,58 @@ ELSE () | |||
ENDIF() | |||
ENDIF() | |||
|
|||
IF (USE_HTTPS STREQUAL "ON") | |||
IF (SECURITY_FOUND) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit strange that we're actually searching for the security framewok even if USE_HTTPS=OFF
here. But we can improve that later, no need to do it as part of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, USE_TLS=OFF
should disable all crypto-checking we do.
CMakeLists.txt
Outdated
|
||
IF (HTTPS_BACKEND) | ||
ADD_DEFINITIONS(-DGIT_HTTPS) | ||
ENDIF() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing all this code we could even think about making this a separate CMake module later on. Not required for this PR, but I'll tackle this at some point, I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's what I was thinking too, now that the backend selection is in one place 😉.
CMakeLists.txt
Outdated
@@ -303,9 +337,9 @@ IF (USE_SHA1DC) | |||
ELSEIF (WIN32 AND NOT MINGW) | |||
ADD_DEFINITIONS(-DGIT_SHA1_WIN32) | |||
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c) | |||
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | |||
ELSEIF (TLS_BACKEND MATCHES "SecureTransport") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be HTTPS_BACKEND now, shouldn't it? I guess this stems from the fact that I've been using HTTPS with the GIT_HTTPS
define. But actually, GIT_TLS and TLS_BACKEND are nicer names here. So we should certainly be sticking with one name -- I don't care if you want to rename existing usage of GIT_HTTPS to GIT_TLS or if you'll just stick with GIT_HTTPS for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Reverted" patchset to GIT_TLS
then.
CMakeLists.txt
Outdated
ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO) | ||
ELSEIF (OPENSSL_FOUND) | ||
ELSEIF (TLS_BACKEND MATCHES "OpenSSL") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Ah, one additional comment: there are some commit messages without a scope (e.g. "cmake:") in their header. Could you maybe add one where it's missing? :) |
Well, I certainly don't mind at all. It's a bit unfortunate that #4282 is so invasive and clashes with all other PRs touching CMakeLists.txt. We could move forward your PR and I'll try to fix merge conflicts in #4282. By now I've solved enough merge conflicts in there to know the exact steps required to reconstruct the final move, and the other commits are quite localized and as such easy to rebase. Just state your preference and I'll try to adapt accordingly. If you want to move this one forward I'll try to focus on getting it ready and merged such that I can include these changes as soon as possible. |
As it stands, I feel this one is ready. I rebased it just yesterday. |
CMakeLists.txt
Outdated
@@ -544,18 +544,20 @@ ELSE() | |||
ENDIF() | |||
|
|||
IF (SECURITY_FOUND) | |||
ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit does a bit more than its title states, as it also removes the definitions for platform-specific TLS specs. There are additional uses of these defines which you haven't covered in this commit, though:
GIT_SECURE_TRANSPORT
is used in stransport_stream.c and tls_stream.cGIT_OPENSSL
is used in global.h, netops.h, openssl_stream.{c,h}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just an indentation fixup. The defines are still here (line +2).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry. I've been confused by the missing -DGIT_HTTPS
.
CMakeLists.txt
Outdated
@@ -52,7 +53,9 @@ ENDIF() | |||
|
|||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | |||
SET( USE_ICONV ON ) | |||
FIND_PACKAGE(Security) | |||
IF(USE_TLS STREQUAL "OpenSSL" OR USE_TLS STREQUAL "ON") | |||
FIND_PACKAGE(Security) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be IF(USE_TLS STREQUAL "SecureTransport" OR USE_TLS STREQUAL "ON")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix. I'll also check how this reacts to the CommonCrypto hash backend, because I think that checking for Security encompasses CommonCrypto & SecureTransport, so the hash backend might be broken by this change.
CMakeLists.txt
Outdated
@@ -303,9 +339,9 @@ IF (USE_SHA1DC) | |||
ELSEIF (WIN32 AND NOT MINGW) | |||
ADD_DEFINITIONS(-DGIT_SHA1_WIN32) | |||
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c) | |||
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | |||
ELSEIF (TLS_BACKEND MATCHES "SecureTransport") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it should use ${TLS_BACKEND}
, shouldn't it? Shouldn't this use STREQUAL
, as all previous code? Same below for OpenSSL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC CMake original behavior was to always substitute variables in some cases, IF
being one of them.
I'll switch to STREQUAL
though, as TLS_BACKEND
is supposed to be an internal option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, after taking a closer look, this line makes the hash-selection dependent on the backend. Old behavior was "always use CommonCrypto" on macOS, now it's "choose whatever the selected TLS backend provides, except when using SHA1DC". Is that okay ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, that's right. I think it would make more sense to stick with the DARWIN check here instead. Otherwise, it's becoming hard (impossible?) to use the CommonCrypto SHA1 library when TLS is turned off.
I discovered some issues with it (on top of the |
CMakeLists.txt
Outdated
IF(USE_TLS STREQUAL "ON") | ||
IF (SECURITY_FOUND) | ||
# OS X 10.7 and older do not have some functions we use, fall back to OpenSSL there | ||
CHECK_LIBRARY_EXISTS("${SECURITY_DIRS}" SSLCreateContext "Security/SecureTransport.h" HAVE_NEWER_SECURITY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aforementioned issue. Forcing the SecureTransport
backend will skip this test.
Okay, as you wish. Only makes my own life easier :p Thanks for keeping up the work on this! |
861ae4e
to
4bd6da1
Compare
Rebased. I added some commits before tackling the
Something I'm still unsold on is the ability to prefer OpenSSL on macOS ; since we are always choosing CommonCrypto for SHA here and nobody has ever complained about not being able to not link against it, I'll keep it that way (but the fix is easy enough if needed). |
#4282 has landed now, so we can actually continue working on this PR here. |
8117bd7
to
3d4cef5
Compare
Rebased and ready to go ! I've reverted the HTTPS->TLS change (again), because I think it predates 0.26 and I didn't want to break things. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for rebasing! Here's another review. I guess this should be the last round of reviews from my side. I really look forward to merging it as it's much cleaner than what we currently have.
@@ -9,8 +9,8 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the "tls_stream" file special in any way? I'd have expected it to be moved to the "streams" directory, as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix, I remember some conflict when rebasing, which I obviously mishandled.
MESSAGE("-- Found CoreFoundation ${COREFOUNDATION_LIBRARIES}") | ||
ENDIF() | ||
SET(COREFOUNDATION_FOUND TRUE) | ||
SET(COREFOUNDATION_LDFLAGS "-framework CoreFoundation") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LDFLAGS variable may not be set in the first case, where you only check whether COREFOUNDATION_INCLUDE_DIR and COREFOUNDATION_LIBRARIES are set. If you touch this place again, I'd love if you could split this up into two patches: the first one fixes indentation only and the second one introduces your changes. This would make it a bit easier to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a reindent commit before then.
About those changes, what I'm attempting to do is stopping the cmake
run from echoing
-- Found Security /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Security.framework
-- Found CoreFoundation /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/CoreFoundation.framework
on every run. Since after the first run, everything gets cached, so this just short-circuit the test. I can also make both FIND_PACKAGE(... QUIET REQUIRED)
, but this silences it completely...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up removing my bad attempt at using the cache correctly.
cmake/Modules/FindSecurity.cmake
Outdated
MESSAGE("-- Found Security ${SECURITY_LIBRARIES}") | ||
ENDIF() | ||
SET(SECURITY_FOUND TRUE) | ||
SET(SECURITY_LDFLAGS "-framework Security") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as for the other module changes. Here, both SECURITY_LDFLAGS and SECURITY_HAS_SSLCREATECONTEXT may be missing in the first case.
src/CMakeLists.txt
Outdated
ELSE() | ||
MESSAGE("-- Security framework is too old, falling back to OpenSSL") | ||
SET(USE_OPENSSL "ON") | ||
ENDIF() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to see that the main CMakeLists.txt becomes easier to read :)
CMakeLists.txt
Outdated
@@ -51,6 +52,7 @@ OPTION( USE_EXT_HTTP_PARSER "Use system HTTP_Parser if available" ON) | |||
OPTION( DEBUG_POOL "Enable debug pool allocator" OFF ) | |||
OPTION( ENABLE_WERROR "Enable compilation with -Werror" OFF ) | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random newline here
CMakeLists.txt
Outdated
@@ -45,6 +45,7 @@ OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF ) | |||
OPTION( USE_SHA1DC "Use SHA-1 with collision detection" OFF ) | |||
OPTION( USE_ICONV "Link with and use iconv library" OFF ) | |||
OPTION( USE_SSH "Link with libssh to enable SSH support" ON ) | |||
OPTION( USE_HTTPS "Enable HTTPS support" ON ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mention that this is not a boolean only but instead can also be a specific backend?
src/CMakeLists.txt
Outdated
ENDIF() | ||
|
||
IF(USE_HTTPS AND NOT HTTPS_BACKEND) | ||
MESSAGE(FATAL_ERROR "Asked for backend ${HTTPS_BACKEND} but it wasn't found") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this cannot happen. If USE_HTTPS is set, then we'll always set it to a value with "OpenSSL" being the fallback. So in case of unknown backends we'll always fail with "OpenSSL not found" above, which is unfortunate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it should trigger when manually asking for a backend we don't support (eg. -DUSE_HTTPS=gnuTLS
). Otherwise, with -DUSE_HTTPS=ON
(the default) the automatic detection will auto-select OpenSSL, which will hard-fail if we can't find OpenSSL (which is what we want, since we can't obey USE_HTTPS).
I'm confused now... I'll try to come up with a cleaner set of IF
blocks then.
Rebased, and added a commit to not link against CoreFoundation when we don't use the SecureTransport backend. Also, I feel like I should tell that CMake's OpenSSL module doesn't work against Homebrew - it ends up linking with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my side, I feel like it is mostly ready to go.
Regarding the Homebrew OpenSSL stuff. Is this something that's being broken by this PR or was it broken before already? If it's the second, I guess we can ignore that for now and fix it in another PR to finally get your changes inside.
MARK_AS_ADVANCED( | ||
COREFOUNDATION_INCLUDE_DIR | ||
COREFOUNDATION_LIBRARIES | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really want to mark those as advanced? I usually see this being used only for internal variables, which is not the case for these here. In CMake, you usually have the pattern
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
MARK_AS_ADVANCED(COREFOUNDATION_LIBRARY)
SET(COREFOUNDATION_LIBRARIES ${COREFOUNDATION_LIBRARY})
So you have an intermediate variable here which is marked as advanced, not the final variable. Same applies to FindSecurity
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was actually looking at some of CMake's modules for inspiration, and I suspect I misread LIBRARY
/LIBRARIES
. Will fix.
FIND_PACKAGE(Security) | ||
FIND_PACKAGE(CoreFoundation) | ||
ENDIF() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this even be moved into STREQUAL "SecureTransport"
? Or is it required somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to have checked for those so the auto-detection works (line 147 below). The other backends have their check before (OpenSSL is at line 125, line 103 is where we just trust WinHTTP is available).
On the OpenSSL point, the CMake module itself looks borked: using I had been able to make it link to the correct libraries somehow with this branch, but I don't think it was possible before those changes (at least not without fixing up what the module fails to do, and obviously if you can fix, then you didn't really have a problem), because I don't think you could prevent the usage of SecureTransport. |
It defaults to ON, e.g. "pick whatever default is appropriate for the platform". It accepts one of SecureTransport, OpenSSL, WinHTTP, or OFF. It errors if the backend library couldn't be found.
This allows us to only link against CoreFoundation when using the SecureTransport backend
@pks-t This is rebased and ready for review ! |
Thanks a lot! I'll review that next week. |
Sorry for taking that long with this PR. Thanks a lot for your patience! |
No sweat ! Imma happy contributor anyways 😉 |
I found my old cmake incantation for building against OpenSSL on macOS, which I'll post here before it's purged from my shell history :
|
Extracted from #4173 and rebased on master, switched to the new HTTPS nomenclature while keeping most of the functional changes.