[backend/federation] Make LD signatures configurable

This commit is contained in:
Laura Hausmann 2024-02-21 18:56:49 +01:00
parent 69e88537bd
commit 399595ad1c
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
5 changed files with 32 additions and 3 deletions

View file

@ -49,6 +49,8 @@ public sealed class Config
public sealed class SecuritySection public sealed class SecuritySection
{ {
public bool AuthorizedFetch { get; init; } = true; public bool AuthorizedFetch { get; init; } = true;
public bool AttachLdSignatures { get; init; } = false;
public bool AcceptLdSignatures { get; init; } = false;
public ExceptionVerbosity ExceptionVerbosity { get; init; } = ExceptionVerbosity.Basic; public ExceptionVerbosity ExceptionVerbosity { get; init; } = ExceptionVerbosity.Basic;
public Enums.Registrations Registrations { get; init; } = Enums.Registrations.Closed; public Enums.Registrations Registrations { get; init; } = Enums.Registrations.Closed;
public Enums.FederationMode FederationMode { get; init; } = Enums.FederationMode.BlockList; public Enums.FederationMode FederationMode { get; init; } = Enums.FederationMode.BlockList;

View file

@ -104,6 +104,14 @@ public static class LdHelpers
return payload; return payload;
} }
public static async Task<string> CompactAsync(this ASActivity activity)
{
var compacted = Compact(activity) ?? throw new Exception("Failed to compact signed activity");
var payload = JsonConvert.SerializeObject(compacted, JsonSerializerSettings);
return payload;
}
public static JObject? Compact(object obj) public static JObject? Compact(object obj)
{ {
return Compact(JToken.FromObject(obj, JsonSerializer)); return Compact(JToken.FromObject(obj, JsonSerializer));

View file

@ -116,7 +116,9 @@ public class AuthorizedFetchMiddleware(
logger.LogDebug("Error validating HTTP signature: {error}", e.Message); logger.LogDebug("Error validating HTTP signature: {error}", e.Message);
} }
if (!verified && request is { ContentType: not null, ContentLength: > 0 }) if (!verified &&
request is { ContentType: not null, ContentLength: > 0 } &&
config.Value.AcceptLdSignatures)
{ {
logger.LogDebug("Trying LD signature next..."); logger.LogDebug("Trying LD signature next...");
try try

View file

@ -1,9 +1,11 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Federation.ActivityStreams; using Iceshrimp.Backend.Core.Federation.ActivityStreams;
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
using Iceshrimp.Backend.Core.Services; using Iceshrimp.Backend.Core.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using ProtoBuf; using ProtoBuf;
using StackExchange.Redis; using StackExchange.Redis;
@ -24,6 +26,7 @@ public class PreDeliverQueue
var logger = scope.GetRequiredService<ILogger<DeliverQueue>>(); var logger = scope.GetRequiredService<ILogger<DeliverQueue>>();
var db = scope.GetRequiredService<DatabaseContext>(); var db = scope.GetRequiredService<DatabaseContext>();
var queueSvc = scope.GetRequiredService<QueueService>(); var queueSvc = scope.GetRequiredService<QueueService>();
var config = scope.GetRequiredService<IOptionsSnapshot<Config.SecuritySection>>();
var parsed = JToken.Parse(job.SerializedActivity); var parsed = JToken.Parse(job.SerializedActivity);
var expanded = LdHelpers.Expand(parsed) ?? throw new Exception("Failed to expand activity"); var expanded = LdHelpers.Expand(parsed) ?? throw new Exception("Failed to expand activity");
@ -64,8 +67,16 @@ public class PreDeliverQueue
if (inboxQueryResults.Count == 0) return; if (inboxQueryResults.Count == 0) return;
string payload;
if (config.Value.AttachLdSignatures)
{
var keypair = await db.UserKeypairs.FirstAsync(p => p.UserId == job.ActorId, token); var keypair = await db.UserKeypairs.FirstAsync(p => p.UserId == job.ActorId, token);
var payload = await activity.SignAndCompactAsync(keypair); payload = await activity.SignAndCompactAsync(keypair);
}
else
{
payload = await activity.CompactAsync();
}
foreach (var inboxQueryResult in inboxQueryResults) foreach (var inboxQueryResult in inboxQueryResults)
await queueSvc.DeliverQueue.EnqueueAsync(new DeliverJob await queueSvc.DeliverQueue.EnqueueAsync(new DeliverJob

View file

@ -18,6 +18,12 @@ CharacterLimit = 8192
;; It is highly recommend you keep this enabled if you intend to use block- or allowlist federation ;; It is highly recommend you keep this enabled if you intend to use block- or allowlist federation
AuthorizedFetch = true AuthorizedFetch = true
;; Whether to attach LD signatures to outgoing activities
AttachLdSignatures = false
;; Whether to accept activities signed using LD signatures
AcceptLdSignatures = false
;; The level of detail in API error responses ;; The level of detail in API error responses
;; Options: [None, Basic, Full] ;; Options: [None, Basic, Full]
ExceptionVerbosity = Basic ExceptionVerbosity = Basic