From ce84aac4270384ff61d7bb8cbd8c572dffa25cab Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Tue, 31 Dec 2024 15:37:07 +0100 Subject: [PATCH] Don't error when initializing LibGit2 with CA roots path When e.g. SSL_CERT_FILE is set, we cannot set this location in LibGit2_jll because it isn't built with support for that. Until now we've errored out with a message telling users to set JULIA_SSL_CA_ROOTS_PATH to an empty string. This changes the behavior to allow this expected error. Variables like SSL_CERT_FILE are for instance set by Conda, ensuring many people running into this, see e.g. https://discourse.julialang.org/search?q=JULIA_SSL_CA_ROOTS_PATH. The other part, and some more context for this, is here: https://github.com/JuliaLang/NetworkOptions.jl/pull/37#issuecomment-2557390529 --- stdlib/LibGit2/src/LibGit2.jl | 16 +++++-------- stdlib/LibGit2/test/bad_ca_roots.jl | 36 +++++++++++++++++++---------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/stdlib/LibGit2/src/LibGit2.jl b/stdlib/LibGit2/src/LibGit2.jl index 04435dd577c19..4eed62331bdbc 100644 --- a/stdlib/LibGit2/src/LibGit2.jl +++ b/stdlib/LibGit2/src/LibGit2.jl @@ -1042,24 +1042,20 @@ function set_ssl_cert_locations(cert_loc) else # files, /dev/null, non-existent paths, etc. cert_file = cert_loc end - ret = @ccall libgit2.git_libgit2_opts( + ret = @ccall libgit2.git_libgit2_opts( Consts.SET_SSL_CERT_LOCATIONS::Cint; cert_file::Cstring, cert_dir::Cstring)::Cint ret >= 0 && return ret + # On macOS and Windows LibGit2_jll is built without a TLS backend that supports + # certificate locations; don't throw on this expected error so we allow certificate + # location environment variables to be set for other purposes. + # We still try doing so to support other LibGit2 builds. err = Error.GitError(ret) err.class == Error.SSL && err.msg == "TLS backend doesn't support certificate locations" || throw(err) - var = nothing - for v in NetworkOptions.CA_ROOTS_VARS - haskey(ENV, v) && (var = v) - end - @assert var !== nothing # otherwise we shouldn't be here - msg = """ - Your Julia is built with a SSL/TLS engine that libgit2 doesn't know how to configure to use a file or directory of certificate authority roots, but your environment specifies one via the $var variable. If you believe your system's root certificates are safe to use, you can `export JULIA_SSL_CA_ROOTS_PATH=""` in your environment to use those instead. - """ - throw(Error.GitError(err.class, err.code, chomp(msg))) + return ret end """ diff --git a/stdlib/LibGit2/test/bad_ca_roots.jl b/stdlib/LibGit2/test/bad_ca_roots.jl index 4882065167bdb..e2abcccc30306 100644 --- a/stdlib/LibGit2/test/bad_ca_roots.jl +++ b/stdlib/LibGit2/test/bad_ca_roots.jl @@ -12,22 +12,34 @@ const CAN_SET_CA_ROOTS_PATH = !Sys.isapple() && !Sys.iswindows() # Given this is a sub-processed test file, not using @testsets avoids # leaking the report print into the Base test runner report begin # empty CA roots file - # these fail for different reasons on different platforms: - # - on Apple & Windows you cannot set the CA roots path location - # - on Linux & FreeBSD you you can but these are invalid files + # different behavior on different platforms: + # - on Apple & Windows you cannot set the CA roots path location; don't error + # - on Linux & FreeBSD you can but these are invalid files + ENV["JULIA_SSL_CA_ROOTS_PATH"] = "/dev/null" - @test_throws LibGit2.GitError LibGit2.ensure_initialized() + if CAN_SET_CA_ROOTS_PATH + err_msg = ["failed to load CA certificates", "format is invalid"] + @test_throws err_msg LibGit2.ensure_initialized() + else + @test LibGit2.ensure_initialized() === nothing + end + ENV["JULIA_SSL_CA_ROOTS_PATH"] = tempname() - @test_throws LibGit2.GitError LibGit2.ensure_initialized() - # test that it still fails if called a second time - @test_throws LibGit2.GitError LibGit2.ensure_initialized() - if !CAN_SET_CA_ROOTS_PATH - # test that this doesn't work on macOS & Windows - ENV["JULIA_SSL_CA_ROOTS_PATH"] = NetworkOptions.bundled_ca_roots() - @test_throws LibGit2.GitError LibGit2.ensure_initialized() - delete!(ENV, "JULIA_SSL_CA_ROOTS_PATH") + if CAN_SET_CA_ROOTS_PATH + err_msg = ["failed to load CA certificates", "Read/write of file failed"] + @test_throws err_msg LibGit2.ensure_initialized() + # test that it still fails if called a second time + @test_throws err_msg LibGit2.ensure_initialized() + else + @test LibGit2.ensure_initialized() === nothing @test LibGit2.ensure_initialized() === nothing end + + ENV["JULIA_SSL_CA_ROOTS_PATH"] = NetworkOptions.bundled_ca_roots() + @test LibGit2.ensure_initialized() === nothing + + delete!(ENV, "JULIA_SSL_CA_ROOTS_PATH") + @test LibGit2.ensure_initialized() === nothing end if CAN_SET_CA_ROOTS_PATH