#![deny(missing_docs)] and lots of documentation
This commit is contained in:
parent
6628d12e13
commit
c56676a601
6 changed files with 83 additions and 4 deletions
|
@ -1,8 +1,11 @@
|
|||
use openssl::error::ErrorStack;
|
||||
|
||||
/// A wrapper enum for things that could go wrong in this crate.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// An error in OpenSSL.
|
||||
OpenSslErrorStack(ErrorStack),
|
||||
/// An error in a SASL mechanism.
|
||||
SaslError(String),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,50 @@
|
|||
//! Provides the `SaslMechanism` trait and some implementations.
|
||||
#![deny(missing_docs)]
|
||||
|
||||
//! This crate provides a framework for SASL authentication and a few authentication mechanisms.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! use sasl::{SaslCredentials, SaslSecret, SaslMechanism, Error};
|
||||
//! use sasl::mechanisms::Plain;
|
||||
//!
|
||||
//! let creds = SaslCredentials {
|
||||
//! username: "user".to_owned(),
|
||||
//! secret: SaslSecret::Password("pencil".to_owned()),
|
||||
//! channel_binding: None,
|
||||
//! };
|
||||
//!
|
||||
//! let mut mechanism = Plain::from_credentials(creds).unwrap();
|
||||
//!
|
||||
//! let initial_data = mechanism.initial().unwrap();
|
||||
//!
|
||||
//! assert_eq!(initial_data, b"\0user\0pencil");
|
||||
//! ```
|
||||
//!
|
||||
//! You may look at the tests of `mechanisms/scram.rs` for examples of more advanced usage.
|
||||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! You can use this in your crate by adding this under `dependencies` in your `Cargo.toml`:
|
||||
//!
|
||||
//! ```toml,ignore
|
||||
//! sasl = "*"
|
||||
//! ```
|
||||
|
||||
extern crate base64;
|
||||
extern crate openssl;
|
||||
|
||||
pub mod error;
|
||||
mod error;
|
||||
|
||||
pub use error::Error;
|
||||
|
||||
/// A struct containing SASL credentials.
|
||||
pub struct SaslCredentials {
|
||||
pub username: String,
|
||||
/// The requested username.
|
||||
pub username: String, // TODO: change this since some mechanisms do not use it
|
||||
/// The secret used to authenticate.
|
||||
pub secret: SaslSecret,
|
||||
/// Optionally, channel binding data, for *-PLUS mechanisms.
|
||||
pub channel_binding: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
|
@ -20,6 +56,7 @@ pub enum SaslSecret {
|
|||
Password(String),
|
||||
}
|
||||
|
||||
/// A trait which defines SASL mechanisms.
|
||||
pub trait SaslMechanism {
|
||||
/// The name of the mechanism.
|
||||
fn name(&self) -> &str;
|
||||
|
|
|
@ -4,9 +4,14 @@ use SaslCredentials;
|
|||
use SaslMechanism;
|
||||
use SaslSecret;
|
||||
|
||||
/// A struct for the SASL ANONYMOUS mechanism.
|
||||
pub struct Anonymous;
|
||||
|
||||
impl Anonymous {
|
||||
/// Constructs a new struct for authenticating using the SASL ANONYMOUS mechanism.
|
||||
///
|
||||
/// It is recommended that instead you use a `SaslCredentials` struct and turn it into the
|
||||
/// requested mechanism using `from_credentials`.
|
||||
pub fn new() -> Anonymous {
|
||||
Anonymous
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
///! Provides a few SASL mechanisms.
|
||||
//! Provides a few SASL mechanisms.
|
||||
|
||||
mod anonymous;
|
||||
mod plain;
|
||||
mod scram;
|
||||
|
|
|
@ -4,12 +4,17 @@ use SaslCredentials;
|
|||
use SaslMechanism;
|
||||
use SaslSecret;
|
||||
|
||||
/// A struct for the SASL PLAIN mechanism.
|
||||
pub struct Plain {
|
||||
username: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
impl Plain {
|
||||
/// Constructs a new struct for authenticating using the SASL PLAIN mechanism.
|
||||
///
|
||||
/// It is recommended that instead you use a `SaslCredentials` struct and turn it into the
|
||||
/// requested mechanism using `from_credentials`.
|
||||
pub fn new<N: Into<String>, P: Into<String>>(username: N, password: P) -> Plain {
|
||||
Plain {
|
||||
username: username.into(),
|
||||
|
|
|
@ -66,13 +66,22 @@ fn generate_nonce() -> Result<String, ErrorStack> {
|
|||
Ok(base64::encode(&data))
|
||||
}
|
||||
|
||||
/// A trait which defines the needed methods for SCRAM.
|
||||
pub trait ScramProvider {
|
||||
/// The name of the hash function.
|
||||
fn name() -> &'static str;
|
||||
|
||||
/// A function which hashes the data using the hash function.
|
||||
fn hash(data: &[u8]) -> Vec<u8>;
|
||||
|
||||
/// A function which performs an HMAC using the hash function.
|
||||
fn hmac(data: &[u8], key: &[u8]) -> Vec<u8>;
|
||||
|
||||
/// A function which does PBKDF2 key derivation using the hash function.
|
||||
fn derive(data: &[u8], salt: &[u8], iterations: usize) -> Vec<u8>;
|
||||
}
|
||||
|
||||
/// A `ScramProvider` which provides SCRAM-SHA-1 and SCRAM-SHA-1-PLUS
|
||||
pub struct Sha1;
|
||||
|
||||
impl ScramProvider for Sha1 {
|
||||
|
@ -99,6 +108,7 @@ impl ScramProvider for Sha1 {
|
|||
}
|
||||
}
|
||||
|
||||
/// A `ScramProvider` which provides SCRAM-SHA-256 and SCRAM-SHA-256-PLUS
|
||||
pub struct Sha256;
|
||||
|
||||
impl ScramProvider for Sha256 {
|
||||
|
@ -136,6 +146,7 @@ enum ScramState {
|
|||
},
|
||||
}
|
||||
|
||||
/// A struct for the SASL SCRAM-* and SCRAM-*-PLUS mechanisms.
|
||||
pub struct Scram<S: ScramProvider> {
|
||||
name: String,
|
||||
username: String,
|
||||
|
@ -147,6 +158,10 @@ pub struct Scram<S: ScramProvider> {
|
|||
}
|
||||
|
||||
impl<S: ScramProvider> Scram<S> {
|
||||
/// Constructs a new struct for authenticating using the SASL SCRAM-* mechanism.
|
||||
///
|
||||
/// It is recommended that instead you use a `SaslCredentials` struct and turn it into the
|
||||
/// requested mechanism using `from_credentials`.
|
||||
pub fn new<N: Into<String>, P: Into<String>>(
|
||||
username: N,
|
||||
password: P,
|
||||
|
@ -162,6 +177,12 @@ impl<S: ScramProvider> Scram<S> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Constructs a new struct for authenticating using the SASL SCRAM-* mechanism.
|
||||
///
|
||||
/// This one takes a nonce instead of generating it.
|
||||
///
|
||||
/// It is recommended that instead you use a `SaslCredentials` struct and turn it into the
|
||||
/// requested mechanism using `from_credentials`.
|
||||
pub fn new_with_nonce<N: Into<String>, P: Into<String>>(
|
||||
username: N,
|
||||
password: P,
|
||||
|
@ -178,11 +199,18 @@ impl<S: ScramProvider> Scram<S> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Constructs a new struct for authenticating using the SASL SCRAM-*-PLUS mechanism.
|
||||
///
|
||||
/// This means that this function will also take the channel binding data.
|
||||
///
|
||||
/// It is recommended that instead you use a `SaslCredentials` struct and turn it into the
|
||||
/// requested mechanism using `from_credentials`.
|
||||
pub fn new_with_channel_binding<N: Into<String>, P: Into<String>>(
|
||||
username: N,
|
||||
password: P,
|
||||
channel_binding: Vec<u8>,
|
||||
) -> Result<Scram<S>, Error> {
|
||||
// TODO: channel binding modes other than tls-unique
|
||||
Ok(Scram {
|
||||
name: format!("SCRAM-{}-PLUS", S::name()),
|
||||
username: username.into(),
|
||||
|
|
Loading…
Reference in a new issue