Skip to content

Commit

Permalink
Don't error when initializing LibGit2 with CA roots path
Browse files Browse the repository at this point in the history
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: JuliaLang/NetworkOptions.jl#37 (comment)
  • Loading branch information
visr committed Dec 31, 2024
1 parent 16230c0 commit ce84aac
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 22 deletions.
16 changes: 6 additions & 10 deletions stdlib/LibGit2/src/LibGit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

"""
Expand Down
36 changes: 24 additions & 12 deletions stdlib/LibGit2/test/bad_ca_roots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ce84aac

Please sign in to comment.