Verify http signatures

This commit is contained in:
Trinity Pointard
2018-10-03 09:31:38 +02:00
parent d610ed1641
commit 0a5d435249
4 changed files with 133 additions and 13 deletions
+33 -3
View File
@@ -1,9 +1,12 @@
use gettextrs::gettext;
use rocket::{request::LenientForm, response::Redirect};
use rocket::{http::HeaderMap, Outcome,
request::{self, FromRequest, LenientForm, Request},
response::Redirect};
use rocket_contrib::{Json, Template};
use serde_json;
use validator::{Validate};
use plume_common::activity_pub::{verify_http_headers, SignatureValidity};
use plume_models::{
admin::Admin,
comments::Comment,
@@ -12,7 +15,6 @@ use plume_models::{
users::User,
safe_string::SafeString,
instance::*
};
use inbox::Inbox;
use routes::Page;
@@ -189,13 +191,41 @@ fn ban(_admin: Admin, conn: DbConn, id: i32) -> Redirect {
Redirect::to(uri!(admin_users))
}
struct Headers<'r> {
headers: HeaderMap<'r>,
}
impl<'a, 'r> FromRequest<'a, 'r> for Headers<'r> {
type Error = ();
fn from_request(request: &'a Request<'r>) ->request::Outcome<Self, ()> {
let mut headers = HeaderMap::new();
for header in request.headers().clone().into_iter() {
headers.add(header);
}
Outcome::Success(Headers{headers})
}
}
#[post("/inbox", data = "<data>")]
fn shared_inbox(conn: DbConn, data: String) -> String {
fn shared_inbox(conn: DbConn, data: String, headers: Headers) -> String {
let act: serde_json::Value = serde_json::from_str(&data[..]).unwrap();
let activity = act.clone();
let actor_id = activity["actor"].as_str()
.unwrap_or_else(|| activity["actor"]["id"].as_str().expect("No actor ID for incoming activity, blocks by panicking"));
let sig = match verify_http_headers(&User::from_url(&conn, actor_id.to_owned()).unwrap(), headers.headers, data) {
SignatureValidity::Valid => true,
_ => {
// TODO verify json signature
false
}
};
if !sig {
return "invalid signature".to_owned();
}
if Instance::is_blocked(&*conn, actor_id.to_string()) {
return String::new();
}