Skip to content

CMake: make HTTPS support more generic#4283

Merged
pks-t merged 11 commits into
libgit2:masterfrom
tiennou:generic-tls
Nov 9, 2017
Merged

CMake: make HTTPS support more generic#4283
pks-t merged 11 commits into
libgit2:masterfrom
tiennou:generic-tls

Conversation

@tiennou

@tiennou tiennou commented Jun 23, 2017

Copy link
Copy Markdown
Contributor

Extracted from #4173 and rebased on master, switched to the new HTTPS nomenclature while keeping most of the functional changes.

@tiennou

tiennou commented Jun 23, 2017

Copy link
Copy Markdown
Contributor Author

@pks-t Here it is ! I'll rebase current #4173 on top of that one while I'm at it.

@pks-t

pks-t commented Jun 24, 2017

Copy link
Copy Markdown
Member

Thanks a lot! Will review in the near future.

@pks-t pks-t left a comment

Copy link
Copy Markdown
Member

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!

Comment thread tests/main.c
if (res < 0) {
return res;
}

Copy link
Copy Markdown
Member

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.

@tiennou tiennou Jul 2, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread src/global.c
#include "filter.h"
#include "merge_driver.h"
#include "openssl_stream.h"
#include "streams/openssl.h"

Copy link
Copy Markdown
Member

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread 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",

Copy link
Copy Markdown
Member

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"?

Copy link
Copy Markdown
Contributor Author

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.

Comment thread src/streams/openssl.c Outdated
return error;
}

int git_openssl_set_cert_file(const char *file, const char *path)

Copy link
Copy Markdown
Member

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".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread src/streams/openssl.h Outdated

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);

Copy link
Copy Markdown
Member

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

Comment thread src/streams/openssl.c Outdated
return -1;
}

int git_openssl_set_ca_location(const char *file, const char *path)

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor Author

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.

Comment thread CMakeLists.txt Outdated
ENDIF()

IF (USE_HTTPS STREQUAL "ON")
IF (SECURITY_FOUND)

Copy link
Copy Markdown
Member

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

Copy link
Copy Markdown
Contributor Author

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.

Comment thread CMakeLists.txt Outdated

IF (HTTPS_BACKEND)
ADD_DEFINITIONS(-DGIT_HTTPS)
ENDIF()

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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 😉.

Comment thread CMakeLists.txt Outdated
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")

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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.

Comment thread CMakeLists.txt Outdated
ELSEIF (TLS_BACKEND MATCHES "SecureTransport")
ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO)
ELSEIF (OPENSSL_FOUND)
ELSEIF (TLS_BACKEND MATCHES "OpenSSL")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@pks-t

pks-t commented Jun 24, 2017

Copy link
Copy Markdown
Member

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? :)

@tiennou

tiennou commented Jul 1, 2017

Copy link
Copy Markdown
Contributor Author

@pks-t Since you've proposed #4282, I'm somewhat wary of touching CMakeLists.txt, so if you don't mind I'll wait until it's merged. I'll go test #4282 though, if that helps.

@pks-t

pks-t commented Jul 3, 2017

Copy link
Copy Markdown
Member

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.

@tiennou

tiennou commented Jul 3, 2017

Copy link
Copy Markdown
Contributor Author

As it stands, I feel this one is ready. I rebased it just yesterday.

Comment thread CMakeLists.txt Outdated
ENDIF()

IF (SECURITY_FOUND)
ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT)

Copy link
Copy Markdown
Member

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.c
  • GIT_OPENSSL is used in global.h, netops.h, openssl_stream.{c,h}

Copy link
Copy Markdown
Contributor Author

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).

Copy link
Copy Markdown
Member

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.

Comment thread CMakeLists.txt Outdated
SET( USE_ICONV ON )
FIND_PACKAGE(Security)
IF(USE_TLS STREQUAL "OpenSSL" OR USE_TLS STREQUAL "ON")
FIND_PACKAGE(Security)

Copy link
Copy Markdown
Member

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")?

Copy link
Copy Markdown
Contributor Author

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.

Comment thread CMakeLists.txt Outdated
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")

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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.

Copy link
Copy Markdown
Contributor Author

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 ?

Copy link
Copy Markdown
Member

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.

@tiennou

tiennou commented Jul 7, 2017

Copy link
Copy Markdown
Contributor Author

I discovered some issues with it (on top of the CommonCrypto thing), so I vote for deferring this one after #4282.

Comment thread 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)

Copy link
Copy Markdown
Contributor Author

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.

@pks-t

pks-t commented Jul 7, 2017

Copy link
Copy Markdown
Member

Okay, as you wish. Only makes my own life easier :p

Thanks for keeping up the work on this!

@tiennou tiennou force-pushed the generic-tls branch 2 times, most recently from 861ae4e to 4bd6da1 Compare August 1, 2017 22:36
@tiennou

tiennou commented Aug 9, 2017

Copy link
Copy Markdown
Contributor Author

Rebased.

I added some commits before tackling the USE_TLS option so the backend selection wouldn't be so messy.

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).

@pks-t

pks-t commented Aug 26, 2017

Copy link
Copy Markdown
Member

#4282 has landed now, so we can actually continue working on this PR here.

@tiennou tiennou force-pushed the generic-tls branch 2 times, most recently from 8117bd7 to 3d4cef5 Compare August 28, 2017 22:17
@tiennou

tiennou commented Aug 29, 2017

Copy link
Copy Markdown
Contributor Author

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.

@tiennou tiennou mentioned this pull request Aug 29, 2017
2 tasks

@pks-t pks-t left a comment

Copy link
Copy Markdown
Member

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.

Comment thread src/tls_stream.c
@@ -9,8 +9,8 @@

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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.

Comment thread cmake/Modules/FindCoreFoundation.cmake Outdated
MESSAGE("-- Found CoreFoundation ${COREFOUNDATION_LIBRARIES}")
ENDIF()
SET(COREFOUNDATION_FOUND TRUE)
SET(COREFOUNDATION_LDFLAGS "-framework CoreFoundation")

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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...

Copy link
Copy Markdown
Contributor Author

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.

Comment thread cmake/Modules/FindSecurity.cmake Outdated
MESSAGE("-- Found Security ${SECURITY_LIBRARIES}")
ENDIF()
SET(SECURITY_FOUND TRUE)
SET(SECURITY_LDFLAGS "-framework Security")

Copy link
Copy Markdown
Member

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.

Comment thread src/CMakeLists.txt Outdated
ELSE()
MESSAGE("-- Security framework is too old, falling back to OpenSSL")
SET(USE_OPENSSL "ON")
ENDIF()

Copy link
Copy Markdown
Member

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 :)

Comment thread CMakeLists.txt Outdated
OPTION( DEBUG_POOL "Enable debug pool allocator" OFF )
OPTION( ENABLE_WERROR "Enable compilation with -Werror" OFF )


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random newline here

Comment thread CMakeLists.txt Outdated
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 )

Copy link
Copy Markdown
Member

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?

Comment thread 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")

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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.

@tiennou

tiennou commented Sep 6, 2017

Copy link
Copy Markdown
Contributor Author

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 /usr/lib/libssl.dylib /usr/lib/libcrypto.dylib, which are the system-supplied versions (0.9.8z IIRC).

@pks-t pks-t left a comment

Copy link
Copy Markdown
Member

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
)

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Contributor Author

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.

Comment thread src/CMakeLists.txt
FIND_PACKAGE(Security)
FIND_PACKAGE(CoreFoundation)
ENDIF()

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Contributor Author

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).

@tiennou

tiennou commented Sep 22, 2017

Copy link
Copy Markdown
Contributor Author

On the OpenSSL point, the CMake module itself looks borked: using -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1, it will use headers from that location but link against stuff in /usr/lib.

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
@tiennou

tiennou commented Oct 24, 2017

Copy link
Copy Markdown
Contributor Author

@pks-t This is rebased and ready for review !

@pks-t

pks-t commented Nov 3, 2017

Copy link
Copy Markdown
Member

Thanks a lot! I'll review that next week.

@pks-t pks-t merged commit 88450c1 into libgit2:master Nov 9, 2017
@pks-t

pks-t commented Nov 9, 2017

Copy link
Copy Markdown
Member

Sorry for taking that long with this PR. Thanks a lot for your patience!

@tiennou

tiennou commented Nov 10, 2017

Copy link
Copy Markdown
Contributor Author

No sweat ! Imma happy contributor anyways 😉

@tiennou tiennou deleted the generic-tls branch November 10, 2017 11:27
@tiennou

tiennou commented Nov 24, 2017

Copy link
Copy Markdown
Contributor Author

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 :

cmake .. -GXcode -DUSE_HTTPS=OpenSSL -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DBUILD_SHARED_LIBS=ON

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants