From 1fc21aed1c9c9c58e8c14a330efdc1cbed5f507e Mon Sep 17 00:00:00 2001 From: asonix Date: Tue, 29 Sep 2020 19:56:41 -0500 Subject: [PATCH] Use http-signature-normalization-reqwest --- Cargo.lock | 24 ++++++++++-- lemmy_apub/Cargo.toml | 4 +- lemmy_apub/src/activity_queue.rs | 12 +----- lemmy_apub/src/extensions/signatures.rs | 51 ++++++++++--------------- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c1e173c2..038dcd469 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1566,9 +1566,9 @@ dependencies = [ [[package]] name = "http-signature-normalization" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee917294413cec0db93a8af6ecfa63730c1d2bb604bd1da69ba75b342fb23f21" +checksum = "cb3a020c37b48d2258910fae9c9b4f8455651f56abfdde1ae68a9397b2765c31" dependencies = [ "chrono", "thiserror", @@ -1592,6 +1592,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "http-signature-normalization-reqwest" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc26a68f8963e26453c7fdea9e016e2e31a48ca018a9223f96afe2cca1a4bd1" +dependencies = [ + "base64 0.12.3", + "bytes", + "chrono", + "futures", + "http", + "http-signature-normalization", + "reqwest", + "sha2", + "thiserror", + "tokio", +] + [[package]] name = "httparse" version = "1.3.4" @@ -1865,8 +1883,8 @@ dependencies = [ "diesel", "futures", "http", - "http-signature-normalization", "http-signature-normalization-actix", + "http-signature-normalization-reqwest", "itertools", "lazy_static", "lemmy_db", diff --git a/lemmy_apub/Cargo.toml b/lemmy_apub/Cargo.toml index 59facad40..eaad7be4d 100644 --- a/lemmy_apub/Cargo.toml +++ b/lemmy_apub/Cargo.toml @@ -33,8 +33,8 @@ url = { version = "2.1", features = ["serde"] } percent-encoding = "2.1" openssl = "0.10" http = "0.2" -http-signature-normalization = "0.5" http-signature-normalization-actix = { version = "0.4", default-features = false, features = ["sha-2"] } +http-signature-normalization-reqwest = { version = "0.1.3", default-features = false, features = ["sha-2"] } base64 = "0.12" tokio = "0.2" futures = "0.3" @@ -45,4 +45,4 @@ async-trait = "0.1" anyhow = "1.0" thiserror = "1.0" background-jobs = " 0.8" -reqwest = { version = "0.10", features = ["json"] } \ No newline at end of file +reqwest = { version = "0.10", features = ["json"] } diff --git a/lemmy_apub/src/activity_queue.rs b/lemmy_apub/src/activity_queue.rs index cb3dbe885..ece782c5d 100644 --- a/lemmy_apub/src/activity_queue.rs +++ b/lemmy_apub/src/activity_queue.rs @@ -77,7 +77,7 @@ impl ActixJob for SendActivityTask { for to_url in &self.to { let mut headers = BTreeMap::::new(); headers.insert("Content-Type".into(), "application/json".into()); - let signed = sign( + let result = sign( &state.client, headers, to_url, @@ -87,15 +87,7 @@ impl ActixJob for SendActivityTask { ) .await; - let signed = match signed { - Ok(s) => s, - Err(e) => { - warn!("{}", e); - // dont return an error because retrying would probably not fix the signing - return Ok(()); - } - }; - if let Err(e) = state.client.execute(signed).await { + if let Err(e) = result { warn!("{}", e); return Err(anyhow!( "Failed to send activity {} to {}", diff --git a/lemmy_apub/src/extensions/signatures.rs b/lemmy_apub/src/extensions/signatures.rs index dd5250685..452b60c66 100644 --- a/lemmy_apub/src/extensions/signatures.rs +++ b/lemmy_apub/src/extensions/signatures.rs @@ -4,8 +4,8 @@ use activitystreams_ext::UnparsedExtension; use actix_web::HttpRequest; use anyhow::{anyhow, Context}; use http::{header::HeaderName, HeaderMap, HeaderValue}; -use http_signature_normalization::Config; -use http_signature_normalization_actix::{digest::DigestCreate, Config as ConfigActix}; +use http_signature_normalization_actix::Config as ConfigActix; +use http_signature_normalization_reqwest::prelude::{Config, SignExt}; use lemmy_utils::{location_info, LemmyError}; use log::debug; use openssl::{ @@ -13,7 +13,7 @@ use openssl::{ pkey::PKey, sign::{Signer, Verifier}, }; -use reqwest::{Client, Request}; +use reqwest::{Client, Response}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::{collections::BTreeMap, str::FromStr}; @@ -27,34 +27,13 @@ lazy_static! { /// Signs request headers with the given keypair. pub async fn sign( client: &Client, - mut headers: BTreeMap, + headers: BTreeMap, url: &Url, activity: String, actor_id: &Url, private_key: String, -) -> Result { +) -> Result { let signing_key_id = format!("{}#main-key", actor_id); - let digest = format!( - "{}={}", - Sha256::NAME, - Sha256::new().compute(activity.as_bytes()) - ); - headers.insert("Digest".into(), digest); - - let mut path_and_query = url.path().to_string(); - if let Some(query) = url.query() { - path_and_query = format!("{}?{}", path_and_query, query); - } - let signature_header_value = HTTP_SIG_CONFIG - .begin_sign("POST", &path_and_query, headers.clone())? - .sign(signing_key_id, |signing_string| { - let private_key = PKey::private_key_from_pem(private_key.as_bytes())?; - let mut signer = Signer::new(MessageDigest::sha256(), &private_key)?; - signer.update(signing_string.as_bytes())?; - - Ok(base64::encode(signer.sign_to_vec()?)) as Result<_, LemmyError> - })? - .signature_header(); let mut header_map = HeaderMap::new(); for h in headers { @@ -63,13 +42,25 @@ pub async fn sign( HeaderValue::from_str(h.1.as_str())?, ); } - let signed_request = client + let response = client .post(&url.to_string()) .headers(header_map) - .header("Signature", signature_header_value) - .body(activity); + .signature_with_digest( + HTTP_SIG_CONFIG.clone(), + signing_key_id, + Sha256::new(), + activity, + move |signing_string| { + let private_key = PKey::private_key_from_pem(private_key.as_bytes())?; + let mut signer = Signer::new(MessageDigest::sha256(), &private_key)?; + signer.update(signing_string.as_bytes())?; - Ok(signed_request.build()?) + Ok(base64::encode(signer.sign_to_vec()?)) as Result<_, LemmyError> + }, + ) + .await?; + + Ok(response) } pub fn verify(request: &HttpRequest, actor: &dyn ActorType) -> Result<(), LemmyError> {