diff --git a/api/schema b/api/schema index a13478a..d5ffd3c 160000 --- a/api/schema +++ b/api/schema @@ -1 +1 @@ -Subproject commit a13478a3f00d6f00580dc344d3a697d90bc50377 +Subproject commit d5ffd3c2b36eecf250639d11c51045740504c2f0 diff --git a/api/src/lib.rs b/api/src/lib.rs index c64b5c2..a33af5a 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -4,7 +4,7 @@ //! This crate contains slightly nicer and better documented bindings for the FabAccess API. -mod schema; +pub mod schema; /// Authentication subsystem pub mod auth { @@ -34,7 +34,7 @@ pub mod role { } pub mod user { - pub use crate::schema::user_capnp::*; + pub use crate::schema::user_capnp::user::*; } pub mod users { @@ -53,4 +53,12 @@ pub mod utils { pub mod l10n_string { pub use crate::schema::utils_capnp::l10_n_string::*; } +} + +pub mod bootstrap { + pub use crate::schema::main_capnp::bootstrap::*; +} + +pub mod session { + pub use crate::schema::main_capnp::session::*; } \ No newline at end of file diff --git a/bffhd/db.rs b/bffhd/db.rs index 7a4659c..30b4f1b 100644 --- a/bffhd/db.rs +++ b/bffhd/db.rs @@ -53,7 +53,7 @@ use rkyv::Deserialize; use rkyv::ser::serializers::AlignedSerializer; use std::sync::Arc; use std::path::Path; -use crate::users::db::{User, UserDB}; +use crate::users::{User, UserDB}; use std::collections::HashMap; use crate::resource::state::{OwnedEntry, State, db::StateDB}; use std::iter::FromIterator; diff --git a/bffhd/server/authentication.rs b/bffhd/server/authentication.rs new file mode 100644 index 0000000..20a275e --- /dev/null +++ b/bffhd/server/authentication.rs @@ -0,0 +1,117 @@ +use api::utils::l10n_string; + +use std::ops::Deref; +use capnp::capability::Promise; +use capnp::Error; +use capnp_rpc::pry; + +use rsasl::{gsasl_err_to_str, SaslError, Session}; +use rsasl::session::Step::{Done, NeedsMore}; + +use api::auth::authentication::{ + Server, + AbortParams, + AbortResults, + StepParams, + StepResults, +}; +use api::auth::response::{ + Reason, + Action, +}; + + +pub struct Authentication { + state: State<()>, +} + +enum State { + InvalidMechanism, + Finished, + Aborted, + Running(Session) +} + +impl Server for Authentication { + fn step(&mut self, params: StepParams, mut results: StepResults) -> Promise<(), Error> { + use State::*; + match self.state { + InvalidMechanism => { + let mut builder = results.get(); + let mut b = builder.init_error(); + b.set_reason(Reason::BadMechanism); + b.set_action(Action::Permanent); + }, + Finished => { + let mut builder = results.get(); + let mut b = builder.init_error(); + b.set_reason(Reason::Finished); + b.set_action(Action::Permanent); + }, + Aborted => { + let mut builder = results.get(); + let mut b = builder.init_error(); + b.set_reason(Reason::Aborted); + b.set_action(Action::Permanent); + }, + Running(ref mut session) => { + // TODO: If null what happens? + let data: &[u8] = pry!(pry!(params.get()).get_data()); + + let mut builder = results.get(); + match session.step(data) { + Ok(Done(Data)) => { + let mut b = builder.init_successful(); + }, + Ok(NeedsMore(Data)) => { + builder.set_challenge(Data.deref()); + }, + Err(e) => { + let mut b = builder.init_error(); + b.set_reason(Reason::Aborted); + b.set_action(Action::Permanent); + } + } + } + } + + Promise::ok(()) + } + + fn abort(&mut self, _: AbortParams, _: AbortResults) -> Promise<(), Error> { + Promise::ok(()) + } +} + +#[repr(transparent)] +struct SaslE { + e: SaslError, +} + +impl l10n_string::Server for SaslE { + fn get(&mut self, + params: l10n_string::GetParams, + mut results: l10n_string::GetResults + ) -> Promise<(), Error> + { + let lang = pry!(pry!(params.get()).get_lang()); + if lang == "en" { + let mut builder = results.get(); + builder.set_lang("en"); + builder.set_content(gsasl_err_to_str(self.e.0)); + } + + Promise::ok(()) + } + + fn available( + &mut self, + _: l10n_string::AvailableParams, + mut results: l10n_string::AvailableResults + ) -> Promise<(), Error> { + let mut builder = results.get(); + let mut langs = builder.init_langs(1); + langs.set(0, "en"); + Promise::ok(()) + } +} \ No newline at end of file diff --git a/bffhd/server/mod.rs b/bffhd/server/mod.rs index 8288d91..62703f3 100644 --- a/bffhd/server/mod.rs +++ b/bffhd/server/mod.rs @@ -1,2 +1,37 @@ +use capnp::capability::Promise; +use capnp::Error; -mod tls; \ No newline at end of file +use api::bootstrap::{ + Server, + MechanismsParams, + MechanismsResults, + CreateSessionParams, + CreateSessionResults +}; + +mod tls; +mod authentication; + +struct ApiSystem { + +} + +impl Server for ApiSystem { + fn mechanisms( + &mut self, + _: MechanismsParams, + _: MechanismsResults + ) -> Promise<(), Error> + { + todo!() + } + + fn create_session( + &mut self, + _: CreateSessionParams, + _: CreateSessionResults + ) -> Promise<(), Error> + { + todo!() + } +} \ No newline at end of file diff --git a/bffhd/users/db.rs b/bffhd/users/db.rs index e26e366..72920dc 100644 --- a/bffhd/users/db.rs +++ b/bffhd/users/db.rs @@ -1,8 +1,9 @@ use std::sync::Arc; use crate::db::{RawDB, DB, AllocAdapter, Environment, Result}; use crate::db::{DatabaseFlags, LMDBorrow, RoTransaction, WriteFlags, }; +use super::User; -use rkyv::{Archive, Serialize, Deserialize, Archived}; +use rkyv::{Deserialize, Archived}; type Adapter = AllocAdapter; #[derive(Clone, Debug)] @@ -11,13 +12,6 @@ pub struct UserDB { db: DB, } -#[derive(Debug, Clone, Archive, Serialize, Deserialize, serde::Serialize, serde::Deserialize)] -pub struct User { - id: u128, - username: String, - roles: Vec, -} - impl UserDB { pub unsafe fn new(env: Arc, db: RawDB) -> Self { let db = DB::new_unchecked(db); diff --git a/bffhd/users/mod.rs b/bffhd/users/mod.rs index ddbe7e8..7562b94 100644 --- a/bffhd/users/mod.rs +++ b/bffhd/users/mod.rs @@ -1,2 +1,43 @@ +use rkyv::{Archive, Serialize, Deserialize}; -pub mod db; \ No newline at end of file +use capnp::capability::Promise; +use capnp::Error; + +use api::user::{ + info, + manage, + admin, +}; + +mod db; +pub use db::UserDB; + +#[derive(Debug, Clone, Archive, Serialize, Deserialize, serde::Serialize, serde::Deserialize)] +pub struct User { + id: u128, + username: String, + roles: Vec, +} + +impl User { + +} + +impl info::Server for User { + fn list_roles( + &mut self, + params: info::ListRolesParams, + mut results: info::ListRolesResults + ) -> Promise<(), Error> + { + Promise::ok(()) + } +} + +impl manage::Server for User { + +} + +impl admin::Server for User { + +} \ No newline at end of file