Complete a full PLAIN authentication round and report the result

This commit is contained in:
Gregor Reitzenstein 2020-11-17 16:13:51 +01:00
parent 5a4f8cc0ec
commit 4a9dd734f8
3 changed files with 50 additions and 20 deletions

View File

@ -10,7 +10,7 @@ use futures_signals::signal::{Mutable, Signal, MutableSignalCloned, MutableLockM
use termion::event::Key; use termion::event::Key;
use crate::input::Inputs; use crate::input::Inputs;
use crate::schema::API; use crate::schema::{API, Authentication};
use crate::commands::{CommandParser, Commands}; use crate::commands::{CommandParser, Commands};
use smol::future::FutureExt; use smol::future::FutureExt;
@ -62,30 +62,37 @@ impl<'a, S: Unpin> Sute<'a, S> {
} }
fn run_cmd(&mut self, cmdline: String) { fn run_cmd(&mut self, cmdline: String) {
let mut words = cmdline.split_ascii_whitespace().map(|s| s.to_string()); let words = cmdline.split_ascii_whitespace().map(|s| s.to_string());
match self.cmds.parse(words) { match self.cmds.parse(words) {
Ok(matches) => { Ok(matches) => {
match matches.subcommand() { match matches.subcommand() {
Some(("quit", _)) => self.state.lock_mut().running = false, Some(("quit", _)) => self.state.lock_mut().running = false,
Some(("authenticate", m)) => { Some(("authenticate", m)) => {
if let Some(mut api) = self.api.clone() { let u = m.value_of("user");
let log2 = self.log.clone(); let p = m.value_of("pass");
info!(self.log, "Going for an auth trip"); if u.is_none() || p.is_none() {
let f = api.authentication().then(move |mut auth| { error!(self.log, "authenticate <user> <pass>");
info!(log2, "Hey, an auth step!");
auth.mechanisms().map(move |mechs| {
info!(log2, "Oh yeah about `authenticate` of yours:");
for mech in mechs {
info!(log2, "Mech: {}", mech);
}
})
});
let old_f = self.future.replace(Box::pin(f));
if !old_f.is_none() {
warn!(self.log, "Dropping a future");
}
} else { } else {
error!(self.log, "No connection, can't authenticate!"); if let Some(mut api) = self.api.clone() {
let log2 = self.log.clone();
info!(self.log, "Going for an auth trip");
let u = u.unwrap().to_string();
let p = p.unwrap().to_string();
let f = api.authentication().then(move |mut auth| {
auth.authenticate(u, p).then(move |res| {
info!(log2, "Authentication result: {}", res);
futures::future::ready(())
})
});
let old_f = self.future.replace(Box::pin(f));
if !old_f.is_none() {
warn!(self.log, "Dropping a future");
}
} else {
error!(self.log, "No connection, can't authenticate!");
}
} }
} }
Some((s, m)) => info!(self.log, "Got Command {} with params {:?}", s, m), Some((s, m)) => info!(self.log, "Got Command {} with params {:?}", s, m),

View File

@ -27,7 +27,7 @@ impl<'help> CommandParser<'help> {
.subcommand(App::new("authenticate") .subcommand(App::new("authenticate")
.arg(Arg::new("user") .arg(Arg::new("user")
.takes_value(true)) .takes_value(true))
.arg(Arg::new("password") .arg(Arg::new("pass")
.takes_value(true)) .takes_value(true))
) )
, ,

View File

@ -31,4 +31,27 @@ impl Authentication {
tmp.get_mechs().unwrap().iter().map(|x| x.unwrap().to_string()).collect() tmp.get_mechs().unwrap().iter().map(|x| x.unwrap().to_string()).collect()
}) })
} }
pub fn authenticate(&mut self, username: String, password: String) -> impl Future<Output=bool> {
let mut req = self.inner.start_request();
let mut builder = req.get().init_request();
builder.set_mechanism("PLAIN");
let mut init_data = builder.init_initial_response();
init_data.set_initial(format!("\0{}\0{}", username, password).as_ref());
let response = req.send().promise;
response.map(|res| {
let res = res.unwrap();
let tmp = res.get().unwrap().get_response().unwrap();
match tmp.which().unwrap() {
super::auth_capnp::response::Which::Challence(_) => false,
super::auth_capnp::response::Which::Outcome(outcome) => {
if outcome.get_result().unwrap() == super::auth_capnp::response::Result::Successful {
return true;
} else {
return false;
}
}
}
})
}
} }