feat/finalize-v0.2 #82
1 changed files with 125 additions and 8 deletions
133
src/auth.rs
133
src/auth.rs
|
@ -24,10 +24,18 @@ use crate::login::ArcLoginProvider;
|
|||
/// S: DONE
|
||||
/// C: VERSION 1 2
|
||||
/// C: CPID 1
|
||||
///
|
||||
/// C: AUTH 2 PLAIN service=smtp
|
||||
/// S: CONT 2
|
||||
/// C: CONT 2 base64stringFollowingRFC4616==
|
||||
/// S: OK 2 user=alice@example.tld
|
||||
///
|
||||
/// C: AUTH 42 LOGIN service=smtp
|
||||
/// S: CONT 42 VXNlcm5hbWU6
|
||||
/// C: CONT 42 b64User
|
||||
/// S: CONT 42 UGFzc3dvcmQ6
|
||||
/// C: CONT 42 b64Pass
|
||||
/// S: FAIL 42 user=alice
|
||||
/// ```
|
||||
///
|
||||
/// ## RFC References
|
||||
|
@ -698,6 +706,44 @@ fn lf_enc(out: &mut BytesMut) {
|
|||
out.put(&[0x0A][..])
|
||||
}
|
||||
|
||||
impl Encode for Mechanism {
|
||||
fn encode(&self, out: &mut BytesMut) -> Result<()> {
|
||||
match self {
|
||||
Self::Plain => out.put(&b"PLAIN"[..]),
|
||||
Self::Login => out.put(&b"LOGIN"[..]),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for MechanismParameters {
|
||||
fn encode(&self, out: &mut BytesMut) -> Result<()> {
|
||||
match self {
|
||||
Self::Anonymous => out.put(&b"anonymous"[..]),
|
||||
Self::PlainText => out.put(&b"plaintext"[..]),
|
||||
Self::Dictionary => out.put(&b"dictionary"[..]),
|
||||
Self::Active => out.put(&b"active"[..]),
|
||||
Self::ForwardSecrecy => out.put(&b"forward-secrecy"[..]),
|
||||
Self::MutualAuth => out.put(&b"mutual-auth"[..]),
|
||||
Self::Private => out.put(&b"private"[..]),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Encode for FailCode {
|
||||
fn encode(&self, out: &mut BytesMut) -> Result<()> {
|
||||
match self {
|
||||
Self::TempFail => out.put(&b"temp_fail"[..]),
|
||||
Self::AuthzFail => out.put(&b"authz_fail"[..]),
|
||||
Self::UserDisabled => out.put(&b"user_disabled"[..]),
|
||||
Self::PassExpired => out.put(&b"pass_expired"[..]),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ServerCommand {
|
||||
fn encode(&self, out: &mut BytesMut) -> Result<()> {
|
||||
match self {
|
||||
|
@ -709,14 +755,85 @@ impl Encode for ServerCommand {
|
|||
out.put(minor.to_string().as_bytes());
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Spid(v) => unimplemented!(),
|
||||
Self::Cuid(v) => unimplemented!(),
|
||||
Self::Mech { kind, parameters } => unimplemented!(),
|
||||
Self::Cookie(v) => unimplemented!(),
|
||||
Self::Done => unimplemented!(),
|
||||
Self::Cont { id, data } => unimplemented!(),
|
||||
Self::Ok { id, user_id, extra_parameters } => unimplemented!(),
|
||||
Self::Fail {id, user_id, code, extra_parameters } => unimplemented!(),
|
||||
Self::Spid(pid) => {
|
||||
out.put(&b"SPID"[..]);
|
||||
tab_enc(out);
|
||||
out.put(pid.to_string().as_bytes());
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Cuid(pid) => {
|
||||
out.put(&b"CUID"[..]);
|
||||
tab_enc(out);
|
||||
out.put(pid.to_string().as_bytes());
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Cookie(cval) => {
|
||||
out.put(&b"COOKIE"[..]);
|
||||
tab_enc(out);
|
||||
out.put(hex::encode(cval).as_bytes());
|
||||
lf_enc(out);
|
||||
|
||||
},
|
||||
Self::Mech { kind, parameters } => {
|
||||
out.put(&b"MECH"[..]);
|
||||
tab_enc(out);
|
||||
kind.encode(out)?;
|
||||
for p in parameters.iter() {
|
||||
tab_enc(out);
|
||||
p.encode(out)?;
|
||||
}
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Done => {
|
||||
out.put(&b"DONE"[..]);
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Cont { id, data } => {
|
||||
out.put(&b"CONT"[..]);
|
||||
tab_enc(out);
|
||||
out.put(id.to_string().as_bytes());
|
||||
if let Some(rdata) = data {
|
||||
tab_enc(out);
|
||||
let b64 = base64::engine::general_purpose::STANDARD.encode(rdata);
|
||||
out.put(b64.as_bytes());
|
||||
}
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Ok { id, user_id, extra_parameters } => {
|
||||
out.put(&b"OK"[..]);
|
||||
tab_enc(out);
|
||||
out.put(id.to_string().as_bytes());
|
||||
if let Some(user) = user_id {
|
||||
tab_enc(out);
|
||||
out.put(&b"user="[..]);
|
||||
out.put(user.as_bytes());
|
||||
}
|
||||
for p in extra_parameters.iter() {
|
||||
tab_enc(out);
|
||||
out.put(&p[..]);
|
||||
}
|
||||
lf_enc(out);
|
||||
},
|
||||
Self::Fail {id, user_id, code, extra_parameters } => {
|
||||
out.put(&b"FAIL"[..]);
|
||||
tab_enc(out);
|
||||
out.put(id.to_string().as_bytes());
|
||||
if let Some(user) = user_id {
|
||||
tab_enc(out);
|
||||
out.put(&b"user="[..]);
|
||||
out.put(user.as_bytes());
|
||||
}
|
||||
if let Some(code_val) = code {
|
||||
tab_enc(out);
|
||||
out.put(&b"code="[..]);
|
||||
code_val.encode(out)?;
|
||||
}
|
||||
for p in extra_parameters.iter() {
|
||||
tab_enc(out);
|
||||
out.put(&p[..]);
|
||||
}
|
||||
lf_enc(out);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue