Merge branch 'auth-fetch-exception' into 'develop'
HTTPSignaturePlug: Add :authorized_fetch_mode_exceptions See merge request pleroma/pleroma!4007
This commit is contained in:
commit
25903a4996
|
@ -0,0 +1 @@
|
||||||
|
HTTPSignaturePlug: Add :authorized_fetch_mode_exceptions configuration
|
|
@ -1816,6 +1816,12 @@
|
||||||
type: :boolean,
|
type: :boolean,
|
||||||
description: "Require HTTP signatures for AP fetches"
|
description: "Require HTTP signatures for AP fetches"
|
||||||
},
|
},
|
||||||
|
%{
|
||||||
|
key: :authorized_fetch_mode_exceptions,
|
||||||
|
type: {:list, :string},
|
||||||
|
description:
|
||||||
|
"List of IPs (CIDR format accepted) to exempt from HTTP Signatures requirement (for example to allow debugging, you shouldn't otherwise need this)"
|
||||||
|
},
|
||||||
%{
|
%{
|
||||||
key: :note_replies_output_limit,
|
key: :note_replies_output_limit,
|
||||||
type: :integer,
|
type: :integer,
|
||||||
|
|
|
@ -284,6 +284,7 @@ Notes:
|
||||||
* `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question
|
* `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question
|
||||||
* `sign_object_fetches`: Sign object fetches with HTTP signatures
|
* `sign_object_fetches`: Sign object fetches with HTTP signatures
|
||||||
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
|
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
|
||||||
|
* `authorized_fetch_mode_exceptions`: List of IPs (CIDR format accepted) to exempt from HTTP Signatures requirement (for example to allow debugging, you shouldn't otherwise need this)
|
||||||
|
|
||||||
## Pleroma.User
|
## Pleroma.User
|
||||||
|
|
||||||
|
|
|
@ -16,4 +16,15 @@ def parse_address(ip) when is_binary(ip) do
|
||||||
def parse_address(ip) do
|
def parse_address(ip) do
|
||||||
:inet.parse_address(ip)
|
:inet.parse_address(ip)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_cidr(proxy) when is_binary(proxy) do
|
||||||
|
proxy =
|
||||||
|
cond do
|
||||||
|
"/" in String.codepoints(proxy) -> proxy
|
||||||
|
InetCidr.v4?(InetCidr.parse_address!(proxy)) -> proxy <> "/32"
|
||||||
|
InetCidr.v6?(InetCidr.parse_address!(proxy)) -> proxy <> "/128"
|
||||||
|
end
|
||||||
|
|
||||||
|
InetCidr.parse_cidr!(proxy, true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
|
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
|
||||||
|
alias Pleroma.Helpers.InetHelper
|
||||||
|
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Phoenix.Controller, only: [get_format: 1, text: 2]
|
import Phoenix.Controller, only: [get_format: 1, text: 2]
|
||||||
require Logger
|
require Logger
|
||||||
|
@ -89,12 +91,20 @@ defp has_signature_header?(conn) do
|
||||||
|
|
||||||
defp maybe_require_signature(%{assigns: %{valid_signature: true}} = conn), do: conn
|
defp maybe_require_signature(%{assigns: %{valid_signature: true}} = conn), do: conn
|
||||||
|
|
||||||
defp maybe_require_signature(conn) do
|
defp maybe_require_signature(%{remote_ip: remote_ip} = conn) do
|
||||||
if Pleroma.Config.get([:activitypub, :authorized_fetch_mode], false) do
|
if Pleroma.Config.get([:activitypub, :authorized_fetch_mode], false) do
|
||||||
conn
|
exceptions =
|
||||||
|> put_status(:unauthorized)
|
Pleroma.Config.get([:activitypub, :authorized_fetch_mode_exceptions], [])
|
||||||
|> text("Request not signed")
|
|> Enum.map(&InetHelper.parse_cidr/1)
|
||||||
|> halt()
|
|
||||||
|
if Enum.any?(exceptions, fn x -> InetCidr.contains?(x, remote_ip) end) do
|
||||||
|
conn
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_status(:unauthorized)
|
||||||
|
|> text("Request not signed")
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
else
|
else
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.Plugs.RemoteIp do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Helpers.InetHelper
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
@behaviour Plug
|
@behaviour Plug
|
||||||
|
@ -30,19 +31,8 @@ defp remote_ip_opts do
|
||||||
proxies =
|
proxies =
|
||||||
Config.get([__MODULE__, :proxies], [])
|
Config.get([__MODULE__, :proxies], [])
|
||||||
|> Enum.concat(reserved)
|
|> Enum.concat(reserved)
|
||||||
|> Enum.map(&maybe_add_cidr/1)
|
|> Enum.map(&InetHelper.parse_cidr/1)
|
||||||
|
|
||||||
{headers, proxies}
|
{headers, proxies}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_add_cidr(proxy) when is_binary(proxy) do
|
|
||||||
proxy =
|
|
||||||
cond do
|
|
||||||
"/" in String.codepoints(proxy) -> proxy
|
|
||||||
InetCidr.v4?(InetCidr.parse_address!(proxy)) -> proxy <> "/32"
|
|
||||||
InetCidr.v6?(InetCidr.parse_address!(proxy)) -> proxy <> "/128"
|
|
||||||
end
|
|
||||||
|
|
||||||
InetCidr.parse_cidr!(proxy, true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -81,5 +81,24 @@ test "halts the connection when `signature` header is not present", %{conn: conn
|
||||||
assert conn.state == :sent
|
assert conn.state == :sent
|
||||||
assert conn.resp_body == "Request not signed"
|
assert conn.resp_body == "Request not signed"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "exempts specific IPs from `authorized_fetch_mode_exceptions`", %{conn: conn} do
|
||||||
|
clear_config([:activitypub, :authorized_fetch_mode_exceptions], ["192.168.0.0/24"])
|
||||||
|
|
||||||
|
with_mock HTTPSignatures, validate_conn: fn _ -> false end do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> Map.put(:remote_ip, {192, 168, 0, 1})
|
||||||
|
|> put_req_header(
|
||||||
|
"signature",
|
||||||
|
"keyId=\"http://mastodon.example.org/users/admin#main-key"
|
||||||
|
)
|
||||||
|
|> HTTPSignaturePlug.call(%{})
|
||||||
|
|
||||||
|
assert conn.remote_ip == {192, 168, 0, 1}
|
||||||
|
assert conn.halted == false
|
||||||
|
assert called(HTTPSignatures.validate_conn(:_))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue