more API simplifications

This commit is contained in:
lumi 2017-03-25 23:45:30 +01:00
parent 35fc26f378
commit 97f597d89d
6 changed files with 34 additions and 55 deletions

View file

@ -22,7 +22,7 @@ pub fn generate_nonce() -> Result<String, ErrorStack> {
/// A trait which defines the needed methods for SCRAM. /// A trait which defines the needed methods for SCRAM.
pub trait ScramProvider { pub trait ScramProvider {
/// The kind of secret this `ScramProvider` requires. /// The kind of secret this `ScramProvider` requires.
type SecretKind: secret::SecretKind; type Secret: secret::Secret;
/// The name of the hash function. /// The name of the hash function.
fn name() -> &'static str; fn name() -> &'static str;
@ -42,7 +42,7 @@ pub struct Sha1;
impl ScramProvider for Sha1 { impl ScramProvider for Sha1 {
// TODO: look at all these unwraps // TODO: look at all these unwraps
type SecretKind = secret::Pbkdf2Sha1; type Secret = secret::Pbkdf2Sha1;
fn name() -> &'static str { fn name() -> &'static str {
"SHA-1" "SHA-1"
@ -105,7 +105,7 @@ pub struct Sha256;
impl ScramProvider for Sha256 { impl ScramProvider for Sha256 {
// TODO: look at all these unwraps // TODO: look at all these unwraps
type SecretKind = secret::Pbkdf2Sha256; type Secret = secret::Pbkdf2Sha256;
fn name() -> &'static str { fn name() -> &'static str {
"SHA-256" "SHA-256"

View file

@ -43,8 +43,8 @@
//! struct MyValidator; //! struct MyValidator;
//! //!
//! impl Validator<secret::Plain> for MyValidator { //! impl Validator<secret::Plain> for MyValidator {
//! fn validate(&self, identity: &Identity, value: &secret::PlainValue) -> Result<(), String> { //! fn validate(&self, identity: &Identity, value: &secret::Plain) -> Result<(), String> {
//! let &secret::PlainValue(ref password) = value; //! let &secret::Plain(ref password) = value;
//! if identity != &Identity::Username(USERNAME.to_owned()) { //! if identity != &Identity::Username(USERNAME.to_owned()) {
//! Err("authentication failed".to_owned()) //! Err("authentication failed".to_owned())
//! } //! }
@ -58,7 +58,7 @@
//! } //! }
//! //!
//! impl Provider<secret::Pbkdf2Sha1> for MyValidator { //! impl Provider<secret::Pbkdf2Sha1> for MyValidator {
//! fn provide(&self, identity: &Identity) -> Result<secret::Pbkdf2Sha1Value, String> { //! fn provide(&self, identity: &Identity) -> Result<secret::Pbkdf2Sha1, String> {
//! if identity != &Identity::Username(USERNAME.to_owned()) { //! if identity != &Identity::Username(USERNAME.to_owned()) {
//! Err("authentication failed".to_owned()) //! Err("authentication failed".to_owned())
//! } //! }
@ -67,7 +67,7 @@
//! ( &Password::Plain((PASSWORD.to_owned())) //! ( &Password::Plain((PASSWORD.to_owned()))
//! , &SALT[..] //! , &SALT[..]
//! , ITERATIONS )?; //! , ITERATIONS )?;
//! Ok(secret::Pbkdf2Sha1Value { //! Ok(secret::Pbkdf2Sha1 {
//! salt: SALT.to_vec(), //! salt: SALT.to_vec(),
//! iterations: ITERATIONS, //! iterations: ITERATIONS,
//! digest: digest, //! digest: digest,
@ -79,7 +79,7 @@
//! impl_validator_using_provider!(MyValidator, secret::Pbkdf2Sha1); //! impl_validator_using_provider!(MyValidator, secret::Pbkdf2Sha1);
//! //!
//! impl Provider<secret::Pbkdf2Sha256> for MyValidator { //! impl Provider<secret::Pbkdf2Sha256> for MyValidator {
//! fn provide(&self, identity: &Identity) -> Result<secret::Pbkdf2Sha256Value, String> { //! fn provide(&self, identity: &Identity) -> Result<secret::Pbkdf2Sha256, String> {
//! if identity != &Identity::Username(USERNAME.to_owned()) { //! if identity != &Identity::Username(USERNAME.to_owned()) {
//! Err("authentication failed".to_owned()) //! Err("authentication failed".to_owned())
//! } //! }
@ -88,7 +88,7 @@
//! ( &Password::Plain((PASSWORD.to_owned())) //! ( &Password::Plain((PASSWORD.to_owned()))
//! , &SALT[..] //! , &SALT[..]
//! , ITERATIONS )?; //! , ITERATIONS )?;
//! Ok(secret::Pbkdf2Sha256Value { //! Ok(secret::Pbkdf2Sha256 {
//! salt: SALT.to_vec(), //! salt: SALT.to_vec(),
//! iterations: ITERATIONS, //! iterations: ITERATIONS,
//! digest: digest, //! digest: digest,

View file

@ -1,39 +1,26 @@
pub trait SecretKind { pub trait Secret {}
type Value: PartialEq;
}
pub trait Pbkdf2SecretValue { pub trait Pbkdf2Secret {
fn salt(&self) -> &[u8]; fn salt(&self) -> &[u8];
fn iterations(&self) -> usize; fn iterations(&self) -> usize;
fn digest(&self) -> &[u8]; fn digest(&self) -> &[u8];
} }
pub struct Plain; #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Plain(pub String);
#[derive(PartialEq)] impl Secret for Plain {}
pub struct PlainValue(pub String);
impl SecretKind for Plain {
type Value = PlainValue;
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Pbkdf2Sha1 { pub struct Pbkdf2Sha1 {
pub salt: Vec<u8>, pub salt: Vec<u8>,
pub iterations: usize, pub iterations: usize,
}
#[derive(PartialEq)]
pub struct Pbkdf2Sha1Value {
pub salt: Vec<u8>,
pub iterations: usize,
pub digest: Vec<u8>, pub digest: Vec<u8>,
} }
impl SecretKind for Pbkdf2Sha1 { impl Secret for Pbkdf2Sha1 {}
type Value = Pbkdf2Sha1Value;
}
impl Pbkdf2SecretValue for Pbkdf2Sha1Value { impl Pbkdf2Secret for Pbkdf2Sha1 {
fn salt(&self) -> &[u8] { fn salt(&self) -> &[u8] {
&self.salt &self.salt
} }
@ -45,23 +32,16 @@ impl Pbkdf2SecretValue for Pbkdf2Sha1Value {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Pbkdf2Sha256 { pub struct Pbkdf2Sha256 {
pub salt: Vec<u8>, pub salt: Vec<u8>,
pub iterations: usize, pub iterations: usize,
}
#[derive(PartialEq)]
pub struct Pbkdf2Sha256Value {
pub salt: Vec<u8>,
pub iterations: usize,
pub digest: Vec<u8>, pub digest: Vec<u8>,
} }
impl SecretKind for Pbkdf2Sha256 { impl Secret for Pbkdf2Sha256 {}
type Value = Pbkdf2Sha256Value;
}
impl Pbkdf2SecretValue for Pbkdf2Sha256Value { impl Pbkdf2Secret for Pbkdf2Sha256 {
fn salt(&self) -> &[u8] { fn salt(&self) -> &[u8] {
&self.salt &self.salt
} }

View file

@ -33,8 +33,7 @@ impl<V: Validator<secret::Plain>> Mechanism for Plain<V> {
let password = let password =
String::from_utf8(password.to_vec()).map_err(|_| "error decoding password")?; String::from_utf8(password.to_vec()).map_err(|_| "error decoding password")?;
let ident = Identity::Username(username); let ident = Identity::Username(username);
self.validator self.validator.validate(&ident, &secret::Plain(password))?;
.validate(&ident, &secret::PlainValue(password))?;
Ok(Response::Success(ident, Vec::new())) Ok(Response::Success(ident, Vec::new()))
} }
} }

View file

@ -5,7 +5,7 @@ use base64;
use common::scram::{generate_nonce, ScramProvider}; use common::scram::{generate_nonce, ScramProvider};
use common::{parse_frame, xor, ChannelBinding, Identity}; use common::{parse_frame, xor, ChannelBinding, Identity};
use secret; use secret;
use secret::Pbkdf2SecretValue; use secret::Pbkdf2Secret;
use server::{Mechanism, Provider, Response}; use server::{Mechanism, Provider, Response};
enum ScramState { enum ScramState {
@ -24,8 +24,8 @@ enum ScramState {
pub struct Scram<S, P> pub struct Scram<S, P>
where where
S: ScramProvider, S: ScramProvider,
P: Provider<S::SecretKind>, P: Provider<S::Secret>,
<S::SecretKind as secret::SecretKind>::Value: secret::Pbkdf2SecretValue, S::Secret: secret::Pbkdf2Secret,
{ {
name: String, name: String,
state: ScramState, state: ScramState,
@ -37,8 +37,8 @@ where
impl<S, P> Scram<S, P> impl<S, P> Scram<S, P>
where where
S: ScramProvider, S: ScramProvider,
P: Provider<S::SecretKind>, P: Provider<S::Secret>,
<S::SecretKind as secret::SecretKind>::Value: secret::Pbkdf2SecretValue, S::Secret: secret::Pbkdf2Secret,
{ {
pub fn new(provider: P, channel_binding: ChannelBinding) -> Scram<S, P> { pub fn new(provider: P, channel_binding: ChannelBinding) -> Scram<S, P> {
Scram { Scram {
@ -54,8 +54,8 @@ where
impl<S, P> Mechanism for Scram<S, P> impl<S, P> Mechanism for Scram<S, P>
where where
S: ScramProvider, S: ScramProvider,
P: Provider<S::SecretKind>, P: Provider<S::Secret>,
<S::SecretKind as secret::SecretKind>::Value: secret::Pbkdf2SecretValue, S::Secret: secret::Pbkdf2Secret,
{ {
fn name(&self) -> &str { fn name(&self) -> &str {
&self.name &self.name

View file

@ -1,5 +1,5 @@
use common::Identity; use common::Identity;
use secret::SecretKind; use secret::Secret;
#[macro_export] #[macro_export]
macro_rules! impl_validator_using_provider { macro_rules! impl_validator_using_provider {
@ -8,7 +8,7 @@ macro_rules! impl_validator_using_provider {
fn validate( fn validate(
&self, &self,
identity: &$crate::common::Identity, identity: &$crate::common::Identity,
value: &<$secret as sasl::secret::SecretKind>::Value, value: &$secret,
) -> Result<(), String> { ) -> Result<(), String> {
if &(self as &$crate::server::Provider<$secret>).provide(identity)? == value { if &(self as &$crate::server::Provider<$secret>).provide(identity)? == value {
Ok(()) Ok(())
@ -20,12 +20,12 @@ macro_rules! impl_validator_using_provider {
}; };
} }
pub trait Provider<S: SecretKind>: Validator<S> { pub trait Provider<S: Secret>: Validator<S> {
fn provide(&self, identity: &Identity) -> Result<S::Value, String>; fn provide(&self, identity: &Identity) -> Result<S, String>;
} }
pub trait Validator<S: SecretKind> { pub trait Validator<S: Secret> {
fn validate(&self, identity: &Identity, value: &S::Value) -> Result<(), String>; fn validate(&self, identity: &Identity, value: &S) -> Result<(), String>;
} }
pub trait Mechanism { pub trait Mechanism {