Mechanisms as bit sets.
This commit is contained in:
parent
e7df79ef68
commit
5765b4b9fe
6 changed files with 164 additions and 176 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -8,9 +8,3 @@ Cargo.lock
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
||||||
# Added by cargo
|
|
||||||
|
|
||||||
/target
|
|
||||||
/Cargo.lock
|
|
||||||
|
|
|
@ -3,9 +3,6 @@ name = "smtp-proto"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
csv = "1.1"
|
|
||||||
|
|
96
src/lib.rs
96
src/lib.rs
|
@ -27,7 +27,7 @@ pub enum Request<T> {
|
||||||
is_last: bool,
|
is_last: bool,
|
||||||
},
|
},
|
||||||
Auth {
|
Auth {
|
||||||
mechanism: Mechanism,
|
mechanism: u64,
|
||||||
initial_response: T,
|
initial_response: T,
|
||||||
},
|
},
|
||||||
Noop {
|
Noop {
|
||||||
|
@ -122,60 +122,55 @@ pub const NOTIFY_SUCCESS: u8 = 0x01;
|
||||||
pub const NOTIFY_FAILURE: u8 = 0x02;
|
pub const NOTIFY_FAILURE: u8 = 0x02;
|
||||||
pub const NOTIFY_DELAY: u8 = 0x04;
|
pub const NOTIFY_DELAY: u8 = 0x04;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
pub const AUTH_SCRAM_SHA_256_PLUS: u64 = 1u64 << 0;
|
||||||
pub enum Mechanism {
|
pub const AUTH_SCRAM_SHA_256: u64 = 1u64 << 1;
|
||||||
_9798MDsaSha1,
|
pub const AUTH_SCRAM_SHA_1_PLUS: u64 = 1u64 << 2;
|
||||||
_9798MEcdsaSha1,
|
pub const AUTH_SCRAM_SHA_1: u64 = 1u64 << 3;
|
||||||
_9798MRsaSha1Enc,
|
pub const AUTH_OAUTHBEARER: u64 = 1u64 << 4;
|
||||||
_9798UDsaSha1,
|
pub const AUTH_XOAUTH: u64 = 1u64 << 5;
|
||||||
_9798UEcdsaSha1,
|
pub const AUTH_XOAUTH2: u64 = 1u64 << 6;
|
||||||
_9798URsaSha1Enc,
|
pub const AUTH_9798_M_DSA_SHA1: u64 = 1u64 << 7;
|
||||||
Anonymous,
|
pub const AUTH_9798_M_ECDSA_SHA1: u64 = 1u64 << 8;
|
||||||
CramMd5,
|
pub const AUTH_9798_M_RSA_SHA1_ENC: u64 = 1u64 << 9;
|
||||||
DigestMd5,
|
pub const AUTH_9798_U_DSA_SHA1: u64 = 1u64 << 10;
|
||||||
EapAes128,
|
pub const AUTH_9798_U_ECDSA_SHA1: u64 = 1u64 << 11;
|
||||||
EapAes128Plus,
|
pub const AUTH_9798_U_RSA_SHA1_ENC: u64 = 1u64 << 12;
|
||||||
EcdhX25519Challenge,
|
pub const AUTH_EAP_AES128: u64 = 1u64 << 13;
|
||||||
EcdsaNist256pChallenge,
|
pub const AUTH_EAP_AES128_PLUS: u64 = 1u64 << 14;
|
||||||
External,
|
pub const AUTH_ECDH_X25519_CHALLENGE: u64 = 1u64 << 15;
|
||||||
Gs2Krb5,
|
pub const AUTH_ECDSA_NIST256P_CHALLENGE: u64 = 1u64 << 16;
|
||||||
Gs2Krb5Plus,
|
pub const AUTH_EXTERNAL: u64 = 1u64 << 17;
|
||||||
GssSpnego,
|
pub const AUTH_GS2_KRB5: u64 = 1u64 << 18;
|
||||||
Gssapi,
|
pub const AUTH_GS2_KRB5_PLUS: u64 = 1u64 << 19;
|
||||||
KerberosV4,
|
pub const AUTH_GSS_SPNEGO: u64 = 1u64 << 20;
|
||||||
KerberosV5,
|
pub const AUTH_GSSAPI: u64 = 1u64 << 21;
|
||||||
Login,
|
pub const AUTH_KERBEROS_V4: u64 = 1u64 << 22;
|
||||||
NmasSambaAuth,
|
pub const AUTH_KERBEROS_V5: u64 = 1u64 << 23;
|
||||||
NmasAuthen,
|
pub const AUTH_NMAS_SAMBA_AUTH: u64 = 1u64 << 24;
|
||||||
NmasLogin,
|
pub const AUTH_NMAS_AUTHEN: u64 = 1u64 << 25;
|
||||||
Ntlm,
|
pub const AUTH_NMAS_LOGIN: u64 = 1u64 << 26;
|
||||||
Oauth10a,
|
pub const AUTH_NTLM: u64 = 1u64 << 27;
|
||||||
Oauthbearer,
|
pub const AUTH_OAUTH10A: u64 = 1u64 << 28;
|
||||||
Openid20,
|
pub const AUTH_OPENID20: u64 = 1u64 << 29;
|
||||||
Otp,
|
pub const AUTH_OTP: u64 = 1u64 << 30;
|
||||||
Plain,
|
pub const AUTH_SAML20: u64 = 1u64 << 31;
|
||||||
Saml20,
|
pub const AUTH_SECURID: u64 = 1u64 << 32;
|
||||||
ScramSha1,
|
pub const AUTH_SKEY: u64 = 1u64 << 33;
|
||||||
ScramSha1Plus,
|
pub const AUTH_SPNEGO: u64 = 1u64 << 34;
|
||||||
ScramSha256,
|
pub const AUTH_SPNEGO_PLUS: u64 = 1u64 << 35;
|
||||||
ScramSha256Plus,
|
pub const AUTH_SXOVER_PLUS: u64 = 1u64 << 36;
|
||||||
Securid,
|
pub const AUTH_CRAM_MD5: u64 = 1u64 << 37;
|
||||||
Skey,
|
pub const AUTH_DIGEST_MD5: u64 = 1u64 << 38;
|
||||||
Spnego,
|
pub const AUTH_LOGIN: u64 = 1u64 << 39;
|
||||||
SpnegoPlus,
|
pub const AUTH_PLAIN: u64 = 1u64 << 40;
|
||||||
SxoverPlus,
|
pub const AUTH_ANONYMOUS: u64 = 1u64 << 41;
|
||||||
Xoauth,
|
|
||||||
Xoauth2,
|
|
||||||
// Unknown
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Capability {
|
pub enum Capability {
|
||||||
EightBitMime,
|
EightBitMime,
|
||||||
Atrn,
|
Atrn,
|
||||||
Auth {
|
Auth {
|
||||||
mechanisms: Vec<Mechanism>,
|
mechanisms: u64,
|
||||||
},
|
},
|
||||||
BinaryMime,
|
BinaryMime,
|
||||||
Burl,
|
Burl,
|
||||||
|
@ -219,6 +214,7 @@ pub enum MtPriority {
|
||||||
Mixer,
|
Mixer,
|
||||||
Stanag4406,
|
Stanag4406,
|
||||||
Nsep,
|
Nsep,
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -279,6 +275,7 @@ impl IntoString for Vec<u8> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
@ -316,3 +313,4 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
|
||||||
use crate::{
|
use crate::*;
|
||||||
Body, By, Error, IntoString, Mechanism, Mtrk, Orcpt, Parameter, Request, Ret, Rrvs, LF,
|
|
||||||
NOTIFY_DELAY, NOTIFY_FAILURE, NOTIFY_SUCCESS, SP,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{receiver::ReceiverParser, *};
|
use super::{receiver::ReceiverParser, *};
|
||||||
|
|
||||||
|
@ -1046,7 +1043,7 @@ impl<'x, 'y> Rfc5321Parser<'x, 'y> {
|
||||||
Ok(params)
|
Ok(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mechanism(&mut self) -> Result<Option<Mechanism>, Error> {
|
pub(crate) fn mechanism(&mut self) -> Result<Option<u64>, Error> {
|
||||||
let mut trailing_chars = [0u8; 8];
|
let mut trailing_chars = [0u8; 8];
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
let mechanism = self.hashed_value_long()?;
|
let mechanism = self.hashed_value_long()?;
|
||||||
|
@ -1069,54 +1066,54 @@ impl<'x, 'y> Rfc5321Parser<'x, 'y> {
|
||||||
bytes_left: self.bytes_left,
|
bytes_left: self.bytes_left,
|
||||||
});
|
});
|
||||||
} else if pos > 8 {
|
} else if pos > 8 {
|
||||||
return Ok(Mechanism::Unknown.into());
|
return Ok(0.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(match (mechanism, &trailing_chars[..pos]) {
|
Ok(match (mechanism, &trailing_chars[..pos]) {
|
||||||
(_9798_M_DSA_SHA1, b"") => Mechanism::_9798MDsaSha1.into(),
|
(_9798_M_DSA_SHA1, b"") => AUTH_9798_M_DSA_SHA1.into(),
|
||||||
(_9798_M_ECDSA_SHA, b"1") => Mechanism::_9798MEcdsaSha1.into(),
|
(_9798_M_ECDSA_SHA, b"1") => AUTH_9798_M_ECDSA_SHA1.into(),
|
||||||
(_9798_M_RSA_SHA1_, b"ENC") => Mechanism::_9798MRsaSha1Enc.into(),
|
(_9798_M_RSA_SHA1_, b"ENC") => AUTH_9798_M_RSA_SHA1_ENC.into(),
|
||||||
(_9798_U_DSA_SHA1, b"") => Mechanism::_9798UDsaSha1.into(),
|
(_9798_U_DSA_SHA1, b"") => AUTH_9798_U_DSA_SHA1.into(),
|
||||||
(_9798_U_ECDSA_SHA, b"1") => Mechanism::_9798UEcdsaSha1.into(),
|
(_9798_U_ECDSA_SHA, b"1") => AUTH_9798_U_ECDSA_SHA1.into(),
|
||||||
(_9798_U_RSA_SHA1_, b"ENC") => Mechanism::_9798URsaSha1Enc.into(),
|
(_9798_U_RSA_SHA1_, b"ENC") => AUTH_9798_U_RSA_SHA1_ENC.into(),
|
||||||
(ANONYMOUS, b"") => Mechanism::Anonymous.into(),
|
(ANONYMOUS, b"") => AUTH_ANONYMOUS.into(),
|
||||||
(CRAM_MD5, b"") => Mechanism::CramMd5.into(),
|
(CRAM_MD5, b"") => AUTH_CRAM_MD5.into(),
|
||||||
(DIGEST_MD5, b"") => Mechanism::DigestMd5.into(),
|
(DIGEST_MD5, b"") => AUTH_DIGEST_MD5.into(),
|
||||||
(EAP_AES128, b"") => Mechanism::EapAes128.into(),
|
(EAP_AES128, b"") => AUTH_EAP_AES128.into(),
|
||||||
(EAP_AES128_PLUS, b"") => Mechanism::EapAes128Plus.into(),
|
(EAP_AES128_PLUS, b"") => AUTH_EAP_AES128_PLUS.into(),
|
||||||
(ECDH_X25519_CHAL, b"LENGE") => Mechanism::EcdhX25519Challenge.into(),
|
(ECDH_X25519_CHAL, b"LENGE") => AUTH_ECDH_X25519_CHALLENGE.into(),
|
||||||
(ECDSA_NIST256P_C, b"HALLENGE") => Mechanism::EcdsaNist256pChallenge.into(),
|
(ECDSA_NIST256P_C, b"HALLENGE") => AUTH_ECDSA_NIST256P_CHALLENGE.into(),
|
||||||
(EXTERNAL, b"") => Mechanism::External.into(),
|
(EXTERNAL, b"") => AUTH_EXTERNAL.into(),
|
||||||
(GS2_KRB5, b"") => Mechanism::Gs2Krb5.into(),
|
(GS2_KRB5, b"") => AUTH_GS2_KRB5.into(),
|
||||||
(GS2_KRB5_PLUS, b"") => Mechanism::Gs2Krb5Plus.into(),
|
(GS2_KRB5_PLUS, b"") => AUTH_GS2_KRB5_PLUS.into(),
|
||||||
(GSS_SPNEGO, b"") => Mechanism::GssSpnego.into(),
|
(GSS_SPNEGO, b"") => AUTH_GSS_SPNEGO.into(),
|
||||||
(GSSAPI, b"") => Mechanism::Gssapi.into(),
|
(GSSAPI, b"") => AUTH_GSSAPI.into(),
|
||||||
(KERBEROS_V4, b"") => Mechanism::KerberosV4.into(),
|
(KERBEROS_V4, b"") => AUTH_KERBEROS_V4.into(),
|
||||||
(KERBEROS_V5, b"") => Mechanism::KerberosV5.into(),
|
(KERBEROS_V5, b"") => AUTH_KERBEROS_V5.into(),
|
||||||
(LOGIN, b"") => Mechanism::Login.into(),
|
(LOGIN, b"") => AUTH_LOGIN.into(),
|
||||||
(NMAS_SAMBA_AUTH, b"") => Mechanism::NmasSambaAuth.into(),
|
(NMAS_SAMBA_AUTH, b"") => AUTH_NMAS_SAMBA_AUTH.into(),
|
||||||
(NMAS_AUTHEN, b"") => Mechanism::NmasAuthen.into(),
|
(NMAS_AUTHEN, b"") => AUTH_NMAS_AUTHEN.into(),
|
||||||
(NMAS_LOGIN, b"") => Mechanism::NmasLogin.into(),
|
(NMAS_LOGIN, b"") => AUTH_NMAS_LOGIN.into(),
|
||||||
(NTLM, b"") => Mechanism::Ntlm.into(),
|
(NTLM, b"") => AUTH_NTLM.into(),
|
||||||
(OAUTH10A, b"") => Mechanism::Oauth10a.into(),
|
(OAUTH10A, b"") => AUTH_OAUTH10A.into(),
|
||||||
(OAUTHBEARER, b"") => Mechanism::Oauthbearer.into(),
|
(OAUTHBEARER, b"") => AUTH_OAUTHBEARER.into(),
|
||||||
(OPENID20, b"") => Mechanism::Openid20.into(),
|
(OPENID20, b"") => AUTH_OPENID20.into(),
|
||||||
(OTP, b"") => Mechanism::Otp.into(),
|
(OTP, b"") => AUTH_OTP.into(),
|
||||||
(PLAIN, b"") => Mechanism::Plain.into(),
|
(PLAIN, b"") => AUTH_PLAIN.into(),
|
||||||
(SAML20, b"") => Mechanism::Saml20.into(),
|
(SAML20, b"") => AUTH_SAML20.into(),
|
||||||
(SCRAM_SHA_1, b"") => Mechanism::ScramSha1.into(),
|
(SCRAM_SHA_1, b"") => AUTH_SCRAM_SHA_1.into(),
|
||||||
(SCRAM_SHA_1_PLUS, b"") => Mechanism::ScramSha1Plus.into(),
|
(SCRAM_SHA_1_PLUS, b"") => AUTH_SCRAM_SHA_1_PLUS.into(),
|
||||||
(SCRAM_SHA_256, b"") => Mechanism::ScramSha256.into(),
|
(SCRAM_SHA_256, b"") => AUTH_SCRAM_SHA_256.into(),
|
||||||
(SCRAM_SHA_256_PL, b"US") => Mechanism::ScramSha256Plus.into(),
|
(SCRAM_SHA_256_PL, b"US") => AUTH_SCRAM_SHA_256_PLUS.into(),
|
||||||
(SECURID, b"") => Mechanism::Securid.into(),
|
(SECURID, b"") => AUTH_SECURID.into(),
|
||||||
(SKEY, b"") => Mechanism::Skey.into(),
|
(SKEY, b"") => AUTH_SKEY.into(),
|
||||||
(SPNEGO, b"") => Mechanism::Spnego.into(),
|
(SPNEGO, b"") => AUTH_SPNEGO.into(),
|
||||||
(SPNEGO_PLUS, b"") => Mechanism::SpnegoPlus.into(),
|
(SPNEGO_PLUS, b"") => AUTH_SPNEGO_PLUS.into(),
|
||||||
(SXOVER_PLUS, b"") => Mechanism::SxoverPlus.into(),
|
(SXOVER_PLUS, b"") => AUTH_SXOVER_PLUS.into(),
|
||||||
(XOAUTH, b"") => Mechanism::Xoauth.into(),
|
(XOAUTH, b"") => AUTH_XOAUTH.into(),
|
||||||
(XOAUTH2, b"") => Mechanism::Xoauth2.into(),
|
(XOAUTH2, b"") => AUTH_XOAUTH2.into(),
|
||||||
(0, b"") => None,
|
(0, b"") => None,
|
||||||
_ => Mechanism::Unknown.into(),
|
_ => 0.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1137,8 +1134,9 @@ impl TryFrom<u128> for Body {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
request::receiver::ReceiverParser, Body, By, Error, Mechanism, Mtrk, Orcpt, Parameter,
|
request::receiver::ReceiverParser, Body, By, Error, Mtrk, Orcpt, Parameter, Request, Ret,
|
||||||
Request, Ret, Rrvs, NOTIFY_DELAY, NOTIFY_FAILURE, NOTIFY_SUCCESS,
|
Rrvs, AUTH_ECDSA_NIST256P_CHALLENGE, AUTH_GSSAPI, AUTH_SCRAM_SHA_256_PLUS, NOTIFY_DELAY,
|
||||||
|
NOTIFY_FAILURE, NOTIFY_SUCCESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1312,28 +1310,28 @@ mod tests {
|
||||||
(
|
(
|
||||||
"AUTH GSSAPI",
|
"AUTH GSSAPI",
|
||||||
Ok(Request::Auth {
|
Ok(Request::Auth {
|
||||||
mechanism: Mechanism::Gssapi,
|
mechanism: AUTH_GSSAPI,
|
||||||
initial_response: "".to_string(),
|
initial_response: "".to_string(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"AUTH ECDSA-NIST256P-CHALLENGE =",
|
"AUTH ECDSA-NIST256P-CHALLENGE =",
|
||||||
Ok(Request::Auth {
|
Ok(Request::Auth {
|
||||||
mechanism: Mechanism::EcdsaNist256pChallenge,
|
mechanism: AUTH_ECDSA_NIST256P_CHALLENGE,
|
||||||
initial_response: "=".to_string(),
|
initial_response: "=".to_string(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"AUTH SCRAM-SHA-256-PLUS base64_goes_here",
|
"AUTH SCRAM-SHA-256-PLUS base64_goes_here",
|
||||||
Ok(Request::Auth {
|
Ok(Request::Auth {
|
||||||
mechanism: Mechanism::ScramSha256Plus,
|
mechanism: AUTH_SCRAM_SHA_256_PLUS,
|
||||||
initial_response: "base64_goes_here".to_string(),
|
initial_response: "base64_goes_here".to_string(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"AUTH ECDSA-NIST256P-CHALLENGE100 abcde",
|
"AUTH ECDSA-NIST256P-CHALLENGE100 abcde",
|
||||||
Ok(Request::Auth {
|
Ok(Request::Auth {
|
||||||
mechanism: Mechanism::Unknown,
|
mechanism: 0,
|
||||||
initial_response: "abcde".to_string(),
|
initial_response: "abcde".to_string(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Capability, Category, EhloResponse, Mechanism, MtPriority, Response, Severity};
|
use crate::*;
|
||||||
|
|
||||||
impl<T: Display> EhloResponse<T> {
|
impl<T: Display> EhloResponse<T> {
|
||||||
pub fn write(&self, mut writer: impl Write) -> io::Result<()> {
|
pub fn write(&self, mut writer: impl Write) -> io::Result<()> {
|
||||||
|
@ -17,8 +17,11 @@ impl<T: Display> EhloResponse<T> {
|
||||||
Capability::Atrn => write!(writer, "ATRN\r\n"),
|
Capability::Atrn => write!(writer, "ATRN\r\n"),
|
||||||
Capability::Auth { mechanisms } => {
|
Capability::Auth { mechanisms } => {
|
||||||
writer.write_all(b"AUTH")?;
|
writer.write_all(b"AUTH")?;
|
||||||
for mechanism in mechanisms {
|
let mut mechanisms = *mechanisms;
|
||||||
write!(writer, " {}", mechanism)?;
|
while mechanisms != 0 {
|
||||||
|
let item = 63 - mechanisms.leading_zeros();
|
||||||
|
mechanisms ^= 1 << item;
|
||||||
|
write!(writer, " {}", (item as u64).as_mechanism())?;
|
||||||
}
|
}
|
||||||
writer.write_all(b"\r\n")
|
writer.write_all(b"\r\n")
|
||||||
}
|
}
|
||||||
|
@ -55,6 +58,7 @@ impl<T: Display> EhloResponse<T> {
|
||||||
MtPriority::Mixer => "MIXER",
|
MtPriority::Mixer => "MIXER",
|
||||||
MtPriority::Stanag4406 => "STANAG4406",
|
MtPriority::Stanag4406 => "STANAG4406",
|
||||||
MtPriority::Nsep => "NSEP",
|
MtPriority::Nsep => "NSEP",
|
||||||
|
MtPriority::None => "MIXER",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
Capability::Mtrk => write!(writer, "MTRK\r\n"),
|
Capability::Mtrk => write!(writer, "MTRK\r\n"),
|
||||||
|
@ -102,53 +106,57 @@ impl<T: Display> Response<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Mechanism {
|
trait AsMechanism {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn as_mechanism(&self) -> &'static str;
|
||||||
f.write_str(match self {
|
}
|
||||||
Mechanism::_9798MDsaSha1 => "9798-M-DSA-SHA1",
|
|
||||||
Mechanism::_9798MEcdsaSha1 => "9798-M-ECDSA-SHA1",
|
impl AsMechanism for u64 {
|
||||||
Mechanism::_9798MRsaSha1Enc => "9798-M-RSA-SHA1-ENC",
|
fn as_mechanism(&self) -> &'static str {
|
||||||
Mechanism::_9798UDsaSha1 => "9798-U-DSA-SHA1",
|
match *self {
|
||||||
Mechanism::_9798UEcdsaSha1 => "9798-U-ECDSA-SHA1",
|
AUTH_SCRAM_SHA_256_PLUS => "SCRAM-SHA-256-PLUS",
|
||||||
Mechanism::_9798URsaSha1Enc => "9798-U-RSA-SHA1-ENC",
|
AUTH_SCRAM_SHA_256 => "SCRAM-SHA-256",
|
||||||
Mechanism::Anonymous => "ANONYMOUS",
|
AUTH_SCRAM_SHA_1_PLUS => "SCRAM-SHA-1-PLUS",
|
||||||
Mechanism::CramMd5 => "CRAM-MD5",
|
AUTH_SCRAM_SHA_1 => "SCRAM-SHA-1",
|
||||||
Mechanism::DigestMd5 => "DIGEST-MD5",
|
AUTH_OAUTHBEARER => "OAUTHBEARER",
|
||||||
Mechanism::EapAes128 => "EAP-AES128",
|
AUTH_XOAUTH => "XOAUTH",
|
||||||
Mechanism::EapAes128Plus => "EAP-AES128-PLUS",
|
AUTH_XOAUTH2 => "XOAUTH2",
|
||||||
Mechanism::EcdhX25519Challenge => "ECDH-X25519-CHALLENGE",
|
AUTH_9798_M_DSA_SHA1 => "9798-M-DSA-SHA1",
|
||||||
Mechanism::EcdsaNist256pChallenge => "ECDSA-NIST256P-CHALLENGE",
|
AUTH_9798_M_ECDSA_SHA1 => "9798-M-ECDSA-SHA1",
|
||||||
Mechanism::External => "EXTERNAL",
|
AUTH_9798_M_RSA_SHA1_ENC => "9798-M-RSA-SHA1-ENC",
|
||||||
Mechanism::Gs2Krb5 => "GS2-KRB5",
|
AUTH_9798_U_DSA_SHA1 => "9798-U-DSA-SHA1",
|
||||||
Mechanism::Gs2Krb5Plus => "GS2-KRB5-PLUS",
|
AUTH_9798_U_ECDSA_SHA1 => "9798-U-ECDSA-SHA1",
|
||||||
Mechanism::GssSpnego => "GSS-SPNEGO",
|
AUTH_9798_U_RSA_SHA1_ENC => "9798-U-RSA-SHA1-ENC",
|
||||||
Mechanism::Gssapi => "GSSAPI",
|
AUTH_EAP_AES128 => "EAP-AES128",
|
||||||
Mechanism::KerberosV4 => "KERBEROS_V4",
|
AUTH_EAP_AES128_PLUS => "EAP-AES128-PLUS",
|
||||||
Mechanism::KerberosV5 => "KERBEROS_V5",
|
AUTH_ECDH_X25519_CHALLENGE => "ECDH-X25519-CHALLENGE",
|
||||||
Mechanism::Login => "LOGIN",
|
AUTH_ECDSA_NIST256P_CHALLENGE => "ECDSA-NIST256P-CHALLENGE",
|
||||||
Mechanism::NmasSambaAuth => "NMAS-SAMBA-AUTH",
|
AUTH_EXTERNAL => "EXTERNAL",
|
||||||
Mechanism::NmasAuthen => "NMAS_AUTHEN",
|
AUTH_GS2_KRB5 => "GS2-KRB5",
|
||||||
Mechanism::NmasLogin => "NMAS_LOGIN",
|
AUTH_GS2_KRB5_PLUS => "GS2-KRB5-PLUS",
|
||||||
Mechanism::Ntlm => "NTLM",
|
AUTH_GSS_SPNEGO => "GSS-SPNEGO",
|
||||||
Mechanism::Oauth10a => "OAUTH10A",
|
AUTH_GSSAPI => "GSSAPI",
|
||||||
Mechanism::Oauthbearer => "OAUTHBEARER",
|
AUTH_KERBEROS_V4 => "KERBEROS_V4",
|
||||||
Mechanism::Openid20 => "OPENID20",
|
AUTH_KERBEROS_V5 => "KERBEROS_V5",
|
||||||
Mechanism::Otp => "OTP",
|
AUTH_NMAS_SAMBA_AUTH => "NMAS-SAMBA-AUTH",
|
||||||
Mechanism::Plain => "PLAIN",
|
AUTH_NMAS_AUTHEN => "NMAS_AUTHEN",
|
||||||
Mechanism::Saml20 => "SAML20",
|
AUTH_NMAS_LOGIN => "NMAS_LOGIN",
|
||||||
Mechanism::ScramSha1 => "SCRAM-SHA-1",
|
AUTH_NTLM => "NTLM",
|
||||||
Mechanism::ScramSha1Plus => "SCRAM-SHA-1-PLUS",
|
AUTH_OAUTH10A => "OAUTH10A",
|
||||||
Mechanism::ScramSha256 => "SCRAM-SHA-256",
|
AUTH_OPENID20 => "OPENID20",
|
||||||
Mechanism::ScramSha256Plus => "SCRAM-SHA-256-PLUS",
|
AUTH_OTP => "OTP",
|
||||||
Mechanism::Securid => "SECURID",
|
AUTH_SAML20 => "SAML20",
|
||||||
Mechanism::Skey => "SKEY",
|
AUTH_SECURID => "SECURID",
|
||||||
Mechanism::Spnego => "SPNEGO",
|
AUTH_SKEY => "SKEY",
|
||||||
Mechanism::SpnegoPlus => "SPNEGO-PLUS",
|
AUTH_SPNEGO => "SPNEGO",
|
||||||
Mechanism::SxoverPlus => "SXOVER-PLUS",
|
AUTH_SPNEGO_PLUS => "SPNEGO-PLUS",
|
||||||
Mechanism::Xoauth => "XOAUTH",
|
AUTH_SXOVER_PLUS => "SXOVER-PLUS",
|
||||||
Mechanism::Xoauth2 => "XOAUTH2",
|
AUTH_CRAM_MD5 => "CRAM-MD5",
|
||||||
Mechanism::Unknown => "",
|
AUTH_DIGEST_MD5 => "DIGEST-MD5",
|
||||||
})
|
AUTH_LOGIN => "LOGIN",
|
||||||
|
AUTH_PLAIN => "PLAIN",
|
||||||
|
AUTH_ANONYMOUS => "ANONYMOUS",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@ impl ReceiverParser for EhloResponse<String> {
|
||||||
_8BITMIME => Capability::EightBitMime,
|
_8BITMIME => Capability::EightBitMime,
|
||||||
ATRN => Capability::Atrn,
|
ATRN => Capability::Atrn,
|
||||||
AUTH => {
|
AUTH => {
|
||||||
let mut mechanisms = Vec::new();
|
let mut mechanisms = 0;
|
||||||
while parser.stop_char != LF {
|
while parser.stop_char != LF {
|
||||||
if let Some(mechanism) = parser.mechanism()? {
|
if let Some(mechanism) = parser.mechanism()? {
|
||||||
mechanisms.push(mechanism);
|
mechanisms |= mechanism;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,10 +306,7 @@ impl Capability {
|
||||||
} else if value.eq_ignore_ascii_case(b"ATRN") {
|
} else if value.eq_ignore_ascii_case(b"ATRN") {
|
||||||
Capability::Atrn.into()
|
Capability::Atrn.into()
|
||||||
} else if value.eq_ignore_ascii_case(b"AUTH") {
|
} else if value.eq_ignore_ascii_case(b"AUTH") {
|
||||||
Capability::Auth {
|
Capability::Auth { mechanisms: 0 }.into()
|
||||||
mechanisms: Vec::new(),
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
} else if value.eq_ignore_ascii_case(b"BINARYMIME") {
|
} else if value.eq_ignore_ascii_case(b"BINARYMIME") {
|
||||||
Capability::BinaryMime.into()
|
Capability::BinaryMime.into()
|
||||||
} else if value.eq_ignore_ascii_case(b"BURL") {
|
} else if value.eq_ignore_ascii_case(b"BURL") {
|
||||||
|
@ -374,8 +371,8 @@ impl Capability {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
request::receiver::ReceiverParser, Capability, EhloResponse, Error, Mechanism, MtPriority,
|
request::receiver::ReceiverParser, Capability, EhloResponse, Error, MtPriority, Response,
|
||||||
Response,
|
AUTH_DIGEST_MD5, AUTH_GSSAPI, AUTH_PLAIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -424,11 +421,7 @@ mod tests {
|
||||||
Capability::EightBitMime,
|
Capability::EightBitMime,
|
||||||
Capability::Atrn,
|
Capability::Atrn,
|
||||||
Capability::Auth {
|
Capability::Auth {
|
||||||
mechanisms: vec![
|
mechanisms: AUTH_GSSAPI | AUTH_DIGEST_MD5 | AUTH_PLAIN,
|
||||||
Mechanism::Gssapi,
|
|
||||||
Mechanism::DigestMd5,
|
|
||||||
Mechanism::Plain,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
Capability::BinaryMime,
|
Capability::BinaryMime,
|
||||||
Capability::Burl,
|
Capability::Burl,
|
||||||
|
|
Loading…
Reference in a new issue