From 6e92ed37320f04b29511f6e3614086cffcab6eb0 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Sat, 29 Dec 2018 00:04:46 -0800 Subject: start trying 'macaroons' crate I initially thought that this might be better than 'macaroon'; macaroons, despite being in "archive" mode, had more crates.io downloads and I hoped might be better implemented. It seems half-complete though, and, eg, doesn't support the V2 macaroon encoding format. This patch isn't complete (didn't figure out verification), but I probably won't pursure it. --- rust/Cargo.lock | 68 +++++------------------------------------------------ rust/Cargo.toml | 2 +- rust/src/auth.rs | 71 ++++++++++++++++++++++++++++++-------------------------- rust/src/lib.rs | 2 +- 4 files changed, 46 insertions(+), 97 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index b76367b0..7adc719d 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -378,7 +378,7 @@ dependencies = [ "iron-test 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "macaroon 0.1.1 (git+https://github.com/bnewbold/libmacaroon-rs?branch=bnewbold-broken)", + "macaroons 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -564,11 +564,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itoa" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" version = "0.4.1" @@ -638,15 +633,12 @@ dependencies = [ ] [[package]] -name = "macaroon" -version = "0.1.1" -source = "git+https://github.com/bnewbold/libmacaroon-rs?branch=bnewbold-broken#346b4bb21c79958dde301501083bfdaa7aa83f73" +name = "macaroons" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libsodium-sys 0.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "sodiumoxide 0.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -769,14 +761,6 @@ dependencies = [ "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-traits" version = "0.2.4" @@ -1115,34 +1099,11 @@ name = "serde" version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "serde" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "serde" version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "serde_codegen_internals" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "serde_derive" version = "1.0.55" @@ -1161,17 +1122,6 @@ dependencies = [ "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "serde_json" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "serde_json" version = "1.0.17" @@ -1631,7 +1581,6 @@ dependencies = [ "checksum iron-slog 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "41941d50d2c936a4c609f457ae8821f9888aa6ed8641f5d6e5d9b22e15041255" "checksum iron-test 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1944bcf30f8b3f51ebf01e715517dd9755e9480934778d6de70179a41d283c1" "checksum isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" @@ -1642,7 +1591,7 @@ dependencies = [ "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum macaroon 0.1.1 (git+https://github.com/bnewbold/libmacaroon-rs?branch=bnewbold-broken)" = "" +"checksum macaroons 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba1d2cf54ae98d8ca803592a3e009522861f7bf7b4178dba7fcffbe0dbe4afa" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" @@ -1657,7 +1606,6 @@ dependencies = [ "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45" "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" @@ -1701,13 +1649,9 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" -"checksum serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" "checksum serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "97f6a6c3caba0cf8f883b53331791036404ce3c1bd895961cf8bb2f8cecfd84b" -"checksum serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc888bd283bd2420b16ad0d860e35ad8acb21941180a83a189bb2046f9d00400" -"checksum serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "978fd866f4d4872084a81ccc35e275158351d3b9fe620074e7d7504b816b74ba" "checksum serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "f51b0ef935cf8a41a77bce553da1f8751a739b7ad82dd73669475a22e6ecedb0" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index a20118d2..278654b5 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -21,7 +21,7 @@ data-encoding = "2.1" regex = "1" lazy_static = "1.0" sha1 = { version = "0.6", features = ["std"] } -macaroon = { git = "https://github.com/bnewbold/libmacaroon-rs", branch = "bnewbold-broken" } +macaroons = "0.3.3" # API server chrono = { version = "0.4", features = ["serde"] } diff --git a/rust/src/auth.rs b/rust/src/auth.rs index 0fe21ebe..f9283329 100644 --- a/rust/src/auth.rs +++ b/rust/src/auth.rs @@ -1,7 +1,10 @@ //! Editor bearer token authentication use swagger::auth::AuthData; -use macaroon::{Format, Macaroon, Verifier}; +use macaroons::v1::V1Token; +use macaroons::verifier::*; +use macaroons::caveat::Caveat; +use macaroons::token::Token; use data_encoding::BASE64; use std::collections::HashMap; @@ -59,51 +62,49 @@ impl AuthConfectionary { } pub fn create_token(&self, editor_id: FatCatId, expires: Option>) -> Result { - let mut mac = Macaroon::create(&self.location, &self.key, &self.identifier).expect("Macaroon creation"); - mac.add_first_party_caveat(&format!("editor_id = {}", editor_id.to_string())); + let mut token = V1Token::new(&self.key, self.identifier.as_bytes().to_vec(), Some(self.location.as_bytes().to_vec())); + token.add_caveat( + &Caveat::first_party(Vec::from(format!("editor_id = {}", editor_id.to_string())))); // TODO: put created one second in the past to prevent timing synchronization glitches? let now = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true); - mac.add_first_party_caveat(&format!("created = {}", now)); + token.add_caveat( + &Caveat::first_party(Vec::from(format!("created = {}", now)))); if let Some(expires) = expires { - mac.add_first_party_caveat(&format!("expires = {:?}", - &expires.to_rfc3339_opts(SecondsFormat::Secs, true))); + token.add_caveat( + &Caveat::first_party(Vec::from(format!("expires = {:?}", + &expires.to_rfc3339_opts(SecondsFormat::Secs, true))))); }; - let raw = mac.serialize(Format::V2).expect("macaroon serialization"); + let raw = token.serialize().expect("macaroon serialization"); Ok(BASE64.encode(&raw)) } /// On success, returns Some((editor_id, scopes)), where `scopes` is a vector of strings. pub fn parse_macaroon_token(&self, conn: &DbConn, s: &str) -> Result { let raw = BASE64.decode(s.as_bytes())?; - let mac = match Macaroon::deserialize(&raw) { + let mac = match V1Token::deserialize(raw) { Ok(m) => m, Err(e) => bail!("macaroon deserialize error: {:?}", e), }; - let mac = match mac.validate() { - Ok(m) => m, - Err(e) => bail!("macaroon validate error: {:?}", e), - }; - let mut verifier = Verifier::new(); let mut editor_id: Option = None; - for caveat in mac.first_party_caveats() { - if caveat.predicate().starts_with("editor_id = ") { - editor_id = Some(FatCatId::from_str(caveat.predicate().get(12..).unwrap())?); + for caveat in mac.caveats.iter() { + let caveat = String::from_utf8_lossy(&caveat.caveat_id); + if caveat.starts_with("editor_id = ") { + editor_id = Some(FatCatId::from_str(caveat.get(12..).unwrap())?); break } } let editor_id = editor_id.expect("expected an editor_id caveat"); - verifier.satisfy_exact(&format!("editor_id = {}", editor_id.to_string())); let mut created: Option> = None; - for caveat in mac.first_party_caveats() { - if caveat.predicate().starts_with("created = ") { - created = Some(DateTime::parse_from_rfc3339(caveat.predicate().get(10..).unwrap()) + for caveat in mac.caveats.iter() { + let caveat = String::from_utf8_lossy(&caveat.caveat_id); + if caveat.starts_with("created = ") { + created = Some(DateTime::parse_from_rfc3339(caveat.get(10..).unwrap()) .unwrap() .with_timezone(&Utc)); break } } let created = created.expect("expected a 'created' caveat"); - verifier.satisfy_exact(&format!("created = {}", created.to_rfc3339_opts(SecondsFormat::Secs, true))); let editor: EditorRow = editor::table .find(&editor_id.to_uuid()) .get_result(conn)?; @@ -111,6 +112,9 @@ impl AuthConfectionary { if created < auth_epoch { bail!("token created before current auth_epoch (was probably revoked by editor)") } + /* XXX: haven't implemented verification + verifier.satisfy_exact(&format!("editor_id = {}", editor_id.to_string())); + verifier.satisfy_exact(&format!("created = {}", created.to_rfc3339_opts(SecondsFormat::Secs, true))); verifier.satisfy_general(|p: &str| -> bool { // not expired (based on expires) if p.starts_with("expires = ") { @@ -122,15 +126,16 @@ impl AuthConfectionary { false } }); - let verify_key = match self.root_keys.get(mac.identifier()) { + let identifier = String::from_utf8_lossy(&mac.identifier).to_string(); + let verify_key = match self.root_keys.get(&identifier) { Some(key) => key, - None => bail!("key not found for identifier: {}", mac.identifier()), + None => bail!("key not found for identifier: {}", identifier), }; match mac.verify(verify_key, &mut verifier) { - Ok(true) => (), - Ok(false) => bail!("token overall verification failed"), + Ok(()) => (), Err(e) => bail!("token parsing failed: {:?}", e), } + */ Ok(editor) } @@ -162,20 +167,20 @@ impl AuthConfectionary { // TODO: refactor out of this file? /// Only used from CLI tool - pub fn inspect_token(&self, conn: &DbConn, token: &str) -> Result<()> { - let raw = BASE64.decode(token.as_bytes())?; - let mac = match Macaroon::deserialize(&raw) { + pub fn inspect_token(&self, conn: &DbConn, raw_token: &str) -> Result<()> { + let raw = BASE64.decode(raw_token.as_bytes())?; + let token = match V1Token::deserialize(raw) { Ok(m) => m, Err(e) => bail!("macaroon deserialize error: {:?}", e), }; let now = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true); println!("current time: {}", now); - println!("domain (location): {:?}", mac.location()); - println!("signing key name (identifier): {}", mac.identifier()); - for caveat in mac.first_party_caveats() { - println!("caveat: {}", caveat.predicate()); + println!("domain (location): {:?}", token.location); + println!("signing key name (identifier): {}", String::from_utf8_lossy(&token.identifier)); + for caveat in token.caveats.iter() { + println!("caveat: {}", String::from_utf8_lossy(&caveat.caveat_id)); } - println!("verify: {:?}", self.parse_macaroon_token(conn, token)); + println!("verify: {:?}", self.parse_macaroon_token(conn, raw_token)); Ok(()) } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 983645d8..b2cfe38a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -23,7 +23,7 @@ extern crate regex; #[macro_use] extern crate lazy_static; extern crate sha1; -extern crate macaroon; +extern crate macaroons; pub mod api_entity_crud; pub mod api_helpers; -- cgit v1.2.3