Add check against instance allowlist etc in shared_inbox

This commit is contained in:
Felix Ableitner 2020-08-01 18:01:24 +02:00
parent e4d5614f3f
commit d845ea66fe
5 changed files with 56 additions and 52 deletions

View File

@ -507,36 +507,36 @@ joinable!(user_mention -> comment (comment_id));
joinable!(user_mention -> user_ (recipient_id));
allow_tables_to_appear_in_same_query!(
activity,
category,
comment,
comment_aggregates_fast,
comment_like,
comment_saved,
community,
community_aggregates_fast,
community_follower,
community_moderator,
community_user_ban,
mod_add,
mod_add_community,
mod_ban,
mod_ban_from_community,
mod_lock_post,
mod_remove_comment,
mod_remove_community,
mod_remove_post,
mod_sticky_post,
password_reset_request,
post,
post_aggregates_fast,
post_like,
post_read,
post_saved,
private_message,
site,
user_,
user_ban,
user_fast,
user_mention,
activity,
category,
comment,
comment_aggregates_fast,
comment_like,
comment_saved,
community,
community_aggregates_fast,
community_follower,
community_moderator,
community_user_ban,
mod_add,
mod_add_community,
mod_ban,
mod_ban_from_community,
mod_lock_post,
mod_remove_comment,
mod_remove_community,
mod_remove_post,
mod_sticky_post,
password_reset_request,
post,
post_aggregates_fast,
post_like,
post_read,
post_saved,
private_message,
site,
user_,
user_ban,
user_fast,
user_mention,
);

View File

@ -1,9 +1,9 @@
use crate::{
apub::{
check_is_apub_id_valid,
community::do_announce,
extensions::signatures::sign,
insert_activity,
is_apub_id_valid,
ActorType,
},
request::retry_custom,
@ -50,10 +50,7 @@ pub async fn send_activity(
for t in to {
let to_url = Url::parse(&t)?;
if !is_apub_id_valid(&to_url) {
debug!("Not sending activity to {} (invalid or blocklisted)", t);
continue;
}
check_is_apub_id_valid(&to_url)?;
let res = retry_custom(|| async {
let request = client.post(&t).header("Content-Type", "application/json");

View File

@ -1,7 +1,7 @@
use crate::{
api::site::SearchResponse,
apub::{
is_apub_id_valid,
check_is_apub_id_valid,
ActorType,
FromApub,
GroupExt,
@ -66,9 +66,7 @@ pub async fn fetch_remote_object<Response>(
where
Response: for<'de> Deserialize<'de>,
{
if !is_apub_id_valid(&url) {
return Err(anyhow!("Activitypub uri invalid or blocked: {}", url).into());
}
check_is_apub_id_valid(&url)?;
let timeout = Duration::from_secs(60);

View File

@ -1,5 +1,6 @@
use crate::{
apub::{
check_is_apub_id_valid,
community::do_announce,
extensions::signatures::verify,
fetcher::{
@ -67,9 +68,13 @@ pub async fn shared_inbox(
debug!("Shared inbox received activity: {}", json);
let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap();
// TODO: pass this actor in instead of using get_user_from_activity()
let actor = get_or_fetch_and_upsert_actor(sender, &client, &pool).await?;
let community = get_community_id_from_activity(&activity).await;
check_is_apub_id_valid(sender)?;
check_is_apub_id_valid(&community)?;
verify(&request, actor.as_ref())?;
insert_activity(actor.user_id(), activity.clone(), false, &pool).await?;
@ -112,6 +117,15 @@ where
get_or_fetch_and_upsert_user(&user_uri, client, pool).await
}
pub(in crate::apub::inbox) async fn get_community_id_from_activity<T, A>(activity: &T) -> Url
where
T: AsBase<A> + ActorAndObjectRef + AsObject<A>,
{
let cc = activity.cc().unwrap();
let cc = cc.as_many().unwrap();
cc.first().unwrap().as_xsd_any_uri().unwrap().to_owned()
}
pub(in crate::apub::inbox) async fn announce_if_community_is_local<T, Kind>(
activity: T,
user: &User_,

View File

@ -63,11 +63,9 @@ where
}
// Checks if the ID has a valid format, correct scheme, and is in the allowed instance list.
fn is_apub_id_valid(apub_id: &Url) -> bool {
debug!("Checking {}", apub_id);
fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
if apub_id.scheme() != get_apub_protocol_string() {
debug!("invalid scheme: {:?}", apub_id.scheme());
return false;
return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into());
}
let allowed_instances: Vec<String> = Settings::get()
@ -81,15 +79,12 @@ fn is_apub_id_valid(apub_id: &Url) -> bool {
let contains = allowed_instances.contains(&d.to_owned());
if !contains {
debug!("{} not in {:?}", d, allowed_instances);
return Err(anyhow!("{} not in federation allowlist", d).into());
}
contains
}
None => {
debug!("missing domain");
false
Ok(())
}
None => Err(anyhow!("federation allowlist is empty").into()),
}
}