mirror of
https://github.com/LemmyNet/activitypub-federation-rust.git
synced 2024-11-15 21:21:03 +00:00
In inbox, verify that http signature digest was verified (ref #1)
This commit is contained in:
parent
da32da5a67
commit
6bec924440
4 changed files with 44 additions and 28 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -631,9 +631,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -641,9 +641,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
|
@ -658,15 +658,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -675,21 +675,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
|
@ -16,7 +16,7 @@ use activitypub_federation::{
|
|||
UrlVerifier,
|
||||
APUB_JSON_CONTENT_TYPE,
|
||||
};
|
||||
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
|
||||
use actix_web::{web, web::Payload, App, HttpRequest, HttpResponse, HttpServer};
|
||||
use async_trait::async_trait;
|
||||
use http_signature_normalization_actix::prelude::VerifyDigest;
|
||||
use reqwest::Client;
|
||||
|
@ -90,8 +90,6 @@ impl Instance {
|
|||
web::scope("")
|
||||
// Important: this ensures that the activity json matches the hashsum in signed
|
||||
// HTTP header
|
||||
// TODO: it would be possible to get rid of this by verifying hash in
|
||||
// receive_activity()
|
||||
.wrap(VerifyDigest::new(Sha256::new()))
|
||||
// Just a single, global inbox for simplicity
|
||||
.route("/inbox", web::post().to(http_post_user_inbox)),
|
||||
|
@ -126,14 +124,13 @@ async fn http_get_user(
|
|||
/// Handles messages received in user inbox
|
||||
async fn http_post_user_inbox(
|
||||
request: HttpRequest,
|
||||
payload: String,
|
||||
payload: Payload,
|
||||
data: web::Data<InstanceHandle>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let data: InstanceHandle = data.into_inner().deref().clone();
|
||||
let activity = serde_json::from_str(&payload)?;
|
||||
receive_activity::<WithContext<PersonAcceptedActivities>, MyUser, InstanceHandle>(
|
||||
request,
|
||||
activity,
|
||||
payload,
|
||||
&data.clone().local_instance,
|
||||
&Data::new(data),
|
||||
)
|
||||
|
|
|
@ -6,14 +6,21 @@ use crate::{
|
|||
Error,
|
||||
LocalInstance,
|
||||
};
|
||||
use actix_web::{HttpRequest, HttpResponse};
|
||||
use actix_web::{
|
||||
web::{Bytes, Payload},
|
||||
FromRequest,
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use http_signature_normalization_actix::prelude::DigestVerified;
|
||||
use serde::de::DeserializeOwned;
|
||||
use tracing::log::debug;
|
||||
use tracing::{log::debug, warn};
|
||||
|
||||
/// Receive an activity and perform some basic checks, including HTTP signature verification.
|
||||
pub async fn receive_activity<Activity, ActorT, Datatype>(
|
||||
request: HttpRequest,
|
||||
activity: Activity,
|
||||
payload: Payload,
|
||||
local_instance: &LocalInstance,
|
||||
data: &Data<Datatype>,
|
||||
) -> Result<HttpResponse, <Activity as ActivityHandler>::Error>
|
||||
|
@ -21,10 +28,25 @@ where
|
|||
Activity: ActivityHandler<DataType = Datatype> + DeserializeOwned + Send + 'static,
|
||||
ActorT: ApubObject<DataType = Datatype> + Actor + Send + 'static,
|
||||
for<'de2> <ActorT as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
<Activity as ActivityHandler>::Error:
|
||||
From<anyhow::Error> + From<Error> + From<<ActorT as ApubObject>::Error>,
|
||||
<Activity as ActivityHandler>::Error: From<anyhow::Error>
|
||||
+ From<Error>
|
||||
+ From<<ActorT as ApubObject>::Error>
|
||||
+ From<serde_json::Error>
|
||||
+ From<http_signature_normalization_actix::digest::middleware::VerifyError>,
|
||||
<ActorT as ApubObject>::Error: From<Error> + From<anyhow::Error>,
|
||||
{
|
||||
let mut payload = payload.into_inner();
|
||||
// ensure that payload hash was checked against digest header by middleware
|
||||
DigestVerified::from_request(&request, &mut payload).await?;
|
||||
|
||||
let bytes = Bytes::from_request(&request, &mut payload)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("{}", e);
|
||||
anyhow!("Failed to parse request body")
|
||||
})?;
|
||||
let activity: Activity = serde_json::from_slice(&bytes)?;
|
||||
|
||||
verify_domains_match(activity.id(), activity.actor())?;
|
||||
verify_url_valid(activity.id(), &local_instance.settings).await?;
|
||||
if local_instance.is_local_url(activity.id()) {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Reference in a new issue