Allow self-signed certificates for gemini

This commit is contained in:
Mike Cifelli 2024-05-04 15:06:40 -04:00
parent 53bfdbd75d
commit fe2000600a
Signed by: mike
GPG Key ID: 6B08C6BE47D08E4C
8 changed files with 37 additions and 5 deletions

View File

@ -5,6 +5,7 @@ defmodule Chronoscope.Gemini.Client do
alias Chronoscope.Gemini.ConnectionClient alias Chronoscope.Gemini.ConnectionClient
@interval_in_seconds 30 @interval_in_seconds 30
@date_time Application.compile_env(:chronoscope, :date_time, DateTime) @date_time Application.compile_env(:chronoscope, :date_time, DateTime)
def start_link(resource: resource, name: name) do def start_link(resource: resource, name: name) do

View File

@ -6,6 +6,7 @@ defmodule Chronoscope.Gemini.ConnectionClient do
alias Chronoscope.Gemini.Response alias Chronoscope.Gemini.Response
@timeout_in_milliseconds 3000 @timeout_in_milliseconds 3000
@ssl Application.compile_env(:chronoscope, :ssl, :ssl) @ssl Application.compile_env(:chronoscope, :ssl, :ssl)
def connect(%{host: host, port: port, path: _} = resource) do def connect(%{host: host, port: port, path: _} = resource) do
@ -25,9 +26,24 @@ defmodule Chronoscope.Gemini.ConnectionClient do
|> @ssl.connect(port, tls_options(host), @timeout_in_milliseconds) |> @ssl.connect(port, tls_options(host), @timeout_in_milliseconds)
end end
defp tls_options(_host) do defp tls_options(host) do
# TODO host
[] |> :tls_certificate_check.options()
|> Keyword.put(:verify_fun, {verify_fun(host), nil})
end
defp verify_fun(hostname) do
hostname_charlist = String.to_charlist(hostname)
fn
certificate, {:bad_cert, :selfsigned_peer}, _state ->
:ssl_verify_hostname.verify_fun(certificate, :valid_peer, check_hostname: hostname_charlist)
{:valid, :selfsigned_peer}
certificate, event, _state ->
IO.inspect(event)
:ssl_verify_hostname.verify_fun(certificate, event, check_hostname: hostname_charlist)
end
end end
defp make_request(socket, url) do defp make_request(socket, url) do

View File

@ -2,6 +2,7 @@ defmodule Chronoscope.NTS.Behaviour do
@callback(key_establishment(host :: String.t(), port :: integer()) :: {:ok, Map.t()}, {:error, any()}) @callback(key_establishment(host :: String.t(), port :: integer()) :: {:ok, Map.t()}, {:error, any()})
end end
# TODO - create macro
defmodule Chronoscope.NTS do defmodule Chronoscope.NTS do
@behaviour Chronoscope.NTS.Behaviour @behaviour Chronoscope.NTS.Behaviour

View File

@ -5,6 +5,7 @@ defmodule Chronoscope.NTS.Client do
alias Chronoscope.NTS.KeyEstablishmentClient alias Chronoscope.NTS.KeyEstablishmentClient
@interval_in_seconds 30 @interval_in_seconds 30
@date_time Application.compile_env(:chronoscope, :date_time, DateTime) @date_time Application.compile_env(:chronoscope, :date_time, DateTime)
def start_link(server: server, name: name) do def start_link(server: server, name: name) do

View File

@ -6,6 +6,7 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
alias Chronoscope.NTS.KeyEstablishmentResponse alias Chronoscope.NTS.KeyEstablishmentResponse
@timeout_in_milliseconds 3000 @timeout_in_milliseconds 3000
@ssl Application.compile_env(:chronoscope, :ssl, :ssl) @ssl Application.compile_env(:chronoscope, :ssl, :ssl)
def key_establishment(%{host: host, port: port}) do def key_establishment(%{host: host, port: port}) do
@ -35,6 +36,7 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
:ok = @ssl.send(socket, KeyEstablishmentRequest.create()) :ok = @ssl.send(socket, KeyEstablishmentRequest.create())
{:ok, peercert} = @ssl.peercert(socket) {:ok, peercert} = @ssl.peercert(socket)
# TODO - refactor?
receive do receive do
{:ssl, _socket, response} -> {:ssl, _socket, response} ->
@ssl.close(socket) @ssl.close(socket)

View File

@ -8,6 +8,7 @@ defmodule ChronoscopeWeb.API.V1.Gemini.ConnectionController do
@default_port 1965 @default_port 1965
@default_path "/" @default_path "/"
@max_host_length 255 @max_host_length 255
@gemini Application.compile_env(:chronoscope, :gemini, Gemini) @gemini Application.compile_env(:chronoscope, :gemini, Gemini)
def get(conn, %{"host" => host, "port" => port, "path" => path}) do def get(conn, %{"host" => host, "port" => port, "path" => path}) do
@ -23,7 +24,11 @@ defmodule ChronoscopeWeb.API.V1.Gemini.ConnectionController do
end end
def get(conn, %{"host" => host, "port" => port}) do def get(conn, %{"host" => host, "port" => port}) do
handle_get(conn, %{host: host, port: port, path: @default_path}) try do
handle_get(conn, %{host: host, port: String.to_integer(port), path: @default_path})
rescue
ArgumentError -> bad_request_response(conn, "invalid port")
end
end end
def get(conn, %{"host" => host}) do def get(conn, %{"host" => host}) do

View File

@ -1,9 +1,14 @@
defmodule ChronoscopeWeb.API.V1.HealthController do defmodule ChronoscopeWeb.API.V1.HealthController do
use ChronoscopeWeb, :controller use ChronoscopeWeb, :controller
alias Chronoscope.Gemini
alias Chronoscope.NTS alias Chronoscope.NTS
def get(conn, _params) do def get(conn, _params) do
json(conn, %{healthy: NTS.healthy?()}) json(conn, %{healthy: healthy?()})
end
defp healthy?() do
NTS.healthy?() && Gemini.healthy?()
end end
end end

View File

@ -7,6 +7,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
@default_port 4460 @default_port 4460
@max_host_length 255 @max_host_length 255
@nts Application.compile_env(:chronoscope, :nts, NTS) @nts Application.compile_env(:chronoscope, :nts, NTS)
def get(conn, %{"host" => host, "port" => port}) do def get(conn, %{"host" => host, "port" => port}) do