feat(http): allow to provide self-signed certificates

Allow for the MOBILIZON_CA_CERT_PATH to be used to provide your own root certificates. The CAStore
and certify certificates stores should be always already be used as fallback instead of the system
store.

Closes #1355

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2024-02-09 12:13:22 +01:00
parent 9d99684402
commit baa11c18b0
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
9 changed files with 49 additions and 8 deletions

View file

@ -85,7 +85,9 @@ defmodule Mobilizon do
ErrorReporting.attach() ErrorReporting.attach()
end end
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor) with :ok <- load_certificates() do
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
end
end end
@spec config_change(keyword, keyword, [atom]) :: :ok @spec config_change(keyword, keyword, [atom]) :: :ok
@ -160,4 +162,16 @@ defmodule Mobilizon do
end end
defp setup_ecto_dev_logger(_), do: nil defp setup_ecto_dev_logger(_), do: nil
defp load_certificates do
custom_cert_path = System.get_env("MOBILIZON_CA_CERT_PATH")
if is_binary(custom_cert_path) do
with :ok <- :tls_certificate_check.override_trusted_authorities({:file, custom_cert_path}) do
:public_key.cacerts_load(custom_cert_path)
end
else
:ok
end
end
end end

View file

@ -3,7 +3,9 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
Tesla HTTP Client that is preconfigured to get and post ActivityPub content Tesla HTTP Client that is preconfigured to get and post ActivityPub content
""" """
require Logger
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
@ -13,7 +15,11 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
def client(options \\ []) do def client(options \\ []) do
headers = Keyword.get(options, :headers, []) headers = Keyword.get(options, :headers, [])
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
opts =
@default_opts
|> Keyword.merge(ssl_options: get_tls_config())
|> Keyword.merge(Keyword.get(options, :opts, []))
middleware = [ middleware = [
{Tesla.Middleware.Headers, {Tesla.Middleware.Headers,

View file

@ -4,6 +4,7 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
""" """
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
@ -13,7 +14,11 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
def client(options \\ []) do def client(options \\ []) do
headers = Keyword.get(options, :headers, []) headers = Keyword.get(options, :headers, [])
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
opts =
@default_opts
|> Keyword.merge(ssl_options: get_tls_config())
|> Keyword.merge(Keyword.get(options, :opts, []))
middleware = [ middleware = [
{Tesla.Middleware.Headers, {Tesla.Middleware.Headers,

View file

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.GeospatialClient do
use Tesla use Tesla
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
] ]
adapter(Tesla.Adapter.Hackney, @default_opts) adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects) plug(Tesla.Middleware.FollowRedirects)

View file

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.HostMetaClient do
use Tesla use Tesla
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
] ]
adapter(Tesla.Adapter.Hackney, @default_opts) adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects) plug(Tesla.Middleware.FollowRedirects)

View file

@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RemoteMediaDownloaderClient do
use Tesla use Tesla
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
] ]
adapter(Tesla.Adapter.Hackney, @default_opts) adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects) plug(Tesla.Middleware.FollowRedirects)

View file

@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RichMediaPreviewClient do
use Tesla use Tesla
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
] ]
adapter(Tesla.Adapter.Hackney, @default_opts) adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects) plug(Tesla.Middleware.FollowRedirects)

View file

@ -3,6 +3,17 @@ defmodule Mobilizon.Service.HTTP.Utils do
Utils for HTTP operations Utils for HTTP operations
""" """
def get_tls_config do
cacertfile =
if is_nil(System.get_env("MOBILIZON_CA_CERT_PATH")) do
CAStore.file_path()
else
System.get_env("MOBILIZON_CA_CERT_PATH")
end
[cacertfile: cacertfile]
end
@spec get_header(Enum.t(), String.t()) :: String.t() | nil @spec get_header(Enum.t(), String.t()) :: String.t() | nil
def get_header(headers, key) do def get_header(headers, key) do
key = String.downcase(key) key = String.downcase(key)

View file

@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.WebfingerClient do
use Tesla use Tesla
alias Mobilizon.Config alias Mobilizon.Config
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
@default_opts [ @default_opts [
recv_timeout: 20_000 recv_timeout: 20_000
] ]
adapter(Tesla.Adapter.Hackney, @default_opts) adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
plug(Tesla.Middleware.FollowRedirects) plug(Tesla.Middleware.FollowRedirects)