From c2325f4d6a0c81ae332f277ca316885ad42c6574 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 22 Feb 2021 22:15:43 +0100 Subject: [PATCH] Use NetworkOptions stdlib for default value of host verification. --- Project.toml | 1 + src/ConnectionPool.jl | 7 ++++--- src/HTTP.jl | 2 +- test/client.jl | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 25a08d6a6..21d249f91 100644 --- a/Project.toml +++ b/Project.toml @@ -8,6 +8,7 @@ Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" IniFile = "83e8ac13-25f8-5344-8a64-a9f2b223428f" MbedTLS = "739be429-bea8-5141-9913-cc70e7f3736d" +NetworkOptions = "ca575930-c2e3-43a9-ace4-1e988b2c1908" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" diff --git a/src/ConnectionPool.jl b/src/ConnectionPool.jl index 929b2cd4e..e59870c43 100644 --- a/src/ConnectionPool.jl +++ b/src/ConnectionPool.jl @@ -32,6 +32,7 @@ using ..IOExtras, ..Sockets import ..@debug, ..@debugshow, ..DEBUG_LEVEL, ..taskid import ..@require, ..precondition_error, ..@ensure, ..postcondition_error using MbedTLS: SSLConfig, SSLContext, setup!, associate!, hostname!, handshake! +import NetworkOptions const default_connection_limit = 8 const default_pipeline_limit = 16 @@ -543,7 +544,7 @@ function getconnection(::Type{Transaction{T}}, pipeline_limit::Int=default_pipeline_limit, idle_timeout::Int=0, reuse_limit::Int=nolimit, - require_ssl_verification::Bool=true, + require_ssl_verification::Bool=NetworkOptions.verify_host(host, "SSL"), kw...)::Transaction{T} where T <: IO pod = getpod(POOL, hashconn(T, host, port, pipeline_limit, require_ssl_verification, true)) @v1_3 lock(pod.conns) @@ -722,7 +723,7 @@ function getconnection(::Type{SSLContext}, end function sslconnection(tcp::TCPSocket, host::AbstractString; - require_ssl_verification::Bool=true, + require_ssl_verification::Bool=NetworkOptions.verify_host(host, "SSL"), sslconfig::SSLConfig=nosslconfig, kw...)::SSLContext @@ -740,7 +741,7 @@ end function sslupgrade(t::Transaction{TCPSocket}, host::AbstractString; - require_ssl_verification::Bool=true, + require_ssl_verification::Bool=NetworkOptions.verify_host(host, "SSL"), kw...)::Transaction{SSLContext} tls = sslconnection(t.c.io, host; require_ssl_verification=require_ssl_verification, diff --git a/src/HTTP.jl b/src/HTTP.jl index 046bd9d72..77b517ef3 100644 --- a/src/HTTP.jl +++ b/src/HTTP.jl @@ -132,7 +132,7 @@ Status Exception options SSLContext options - - `require_ssl_verification = false`, pass `MBEDTLS_SSL_VERIFY_REQUIRED` to + - `require_ssl_verification = NetworkOptions.verify_host(host)`, pass `MBEDTLS_SSL_VERIFY_REQUIRED` to the mbed TLS library. ["... peer must present a valid certificate, handshake is aborted if verification failed."](https://tls.mbed.org/api/ssl_8h.html#a5695285c9dbfefec295012b566290f37) diff --git a/test/client.jl b/test/client.jl index 4de0cf84a..01f9b430b 100644 --- a/test/client.jl +++ b/test/client.jl @@ -238,6 +238,43 @@ end end end +import NetworkOptions, MbedTLS +@testset "NetworkOptions for host verification" begin + # Set up server with self-signed cert + server = listen(IPv4(0), 8443) + cert, key = joinpath.(@__DIR__, "resources", ("cert.pem", "key.pem")) + sslconfig = MbedTLS.SSLConfig(cert, key) + tsk = @async HTTP.listen("0.0.0.0", 8443; server=server, sslconfig=sslconfig) do http + HTTP.setstatus(http, 200) + HTTP.startwrite(http) + HTTP.write(http, "hello, world") + end + url = "https://localhost:8443" + env = ["JULIA_NO_VERIFY_HOSTS" => nothing, "JULIA_SSL_NO_VERIFY_HOSTS" => nothing, "JULIA_ALWAYS_VERIFY_HOSTS" => nothing] + withenv(env...) do + @test NetworkOptions.verify_host(url) + @test NetworkOptions.verify_host(url, "SSL") + @test_throws HTTP.IOError HTTP.get(url; retries=1) + @test_throws HTTP.IOError HTTP.get(url; require_ssl_verification=true, retries=1) + @test HTTP.get(url; require_ssl_verification=false).status == 200 + end + withenv(env..., "JULIA_NO_VERIFY_HOSTS" => "localhost") do + @test !NetworkOptions.verify_host(url) + @test !NetworkOptions.verify_host(url, "SSL") + @test HTTP.get(url).status == 200 + @test_throws HTTP.IOError HTTP.get(url; require_ssl_verification=true, retries=1) + @test HTTP.get(url; require_ssl_verification=false).status == 200 + end + withenv(env..., "JULIA_SSL_NO_VERIFY_HOSTS" => "localhost") do + @test NetworkOptions.verify_host(url) + @test !NetworkOptions.verify_host(url, "SSL") + @test HTTP.get(url).status == 200 + @test_throws HTTP.IOError HTTP.get(url; require_ssl_verification=true, retries=1) + @test HTTP.get(url; require_ssl_verification=false).status == 200 + end + close(server) +end + @testset "Public entry point of HTTP.request and friends (e.g. issue #463)" begin headers = Dict("User-Agent" => "HTTP.jl") query = Dict("hello" => "world")