From e893869df974ebb7afcc318119840c53f8f377cb Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Sat, 21 Oct 2023 01:28:54 +0100 Subject: implement connection --- src/client/encrypted.rs | 205 ------------------------------------------------ 1 file changed, 205 deletions(-) delete mode 100644 src/client/encrypted.rs (limited to 'src/client/encrypted.rs') diff --git a/src/client/encrypted.rs b/src/client/encrypted.rs deleted file mode 100644 index 263d5ff..0000000 --- a/src/client/encrypted.rs +++ /dev/null @@ -1,205 +0,0 @@ -use std::{collections::BTreeMap, str}; - -use quick_xml::{ - events::{BytesDecl, Event}, - NsReader, Writer, -}; -use rsasl::prelude::{Mechname, SASLClient}; -use tokio::io::{BufReader, ReadHalf, WriteHalf}; -use tokio::net::TcpStream; -use tokio_native_tls::TlsStream; - -use crate::Jabber; -use crate::JabberError; -use crate::Result; - -pub struct JabberClient<'j> { - pub reader: NsReader>>>, - pub writer: Writer>>, - jabber: &'j mut Jabber<'j>, -} - -impl<'j> JabberClient<'j> { - pub fn new( - reader: NsReader>>>, - writer: Writer>>, - jabber: &'j mut Jabber<'j>, - ) -> Self { - Self { - reader, - writer, - jabber, - } - } - - pub async fn start_stream(&mut self) -> Result<()> { - // client to server - let declaration = BytesDecl::new("1.0", None, None); - let server = &self.jabber.server.to_owned().try_into()?; - let stream_element = - Stream::new_client(&self.jabber.jid, server, None, Some("en".to_string())); - self.writer - .write_event_async(Event::Decl(declaration)) - .await; - let stream_element: Element<'_> = stream_element.into(); - stream_element - .write_start(&mut self.writer, &BTreeMap::new()) - .await?; - // server to client - let mut buf = Vec::new(); - self.reader.read_event_into_async(&mut buf).await?; - let _stream_response = Element::read_start(&mut self.reader).await?; - Ok(()) - } - - pub async fn get_features(&mut self) -> Result> { - Element::read(&mut self.reader).await?.try_into() - } - - pub async fn negotiate(&mut self) -> Result<()> { - loop { - println!("negotiate loop"); - let features = self.get_features().await?; - println!("features: {:?}", features); - - match &features[0] { - StreamFeature::Sasl(sasl) => { - println!("sasl?"); - self.sasl(&sasl).await?; - } - StreamFeature::Bind => { - self.bind().await?; - return Ok(()); - } - x => println!("{:?}", x), - } - } - } - - pub async fn watch(&mut self) -> Result<()> { - loop { - let element = Element::read(&mut self.reader).await?; - println!("{:#?}", element); - } - } - - pub async fn sasl(&mut self, mechanisms: &Vec) -> Result<()> { - println!("{:?}", mechanisms); - let sasl = SASLClient::new(self.jabber.auth.clone()); - let mut offered_mechs: Vec<&Mechname> = Vec::new(); - for mechanism in mechanisms { - offered_mechs.push(Mechname::parse(mechanism.as_bytes())?) - } - println!("{:?}", offered_mechs); - let mut session = sasl.start_suggested(&offered_mechs)?; - let selected_mechanism = session.get_mechname().as_str().to_owned(); - println!("selected mech: {:?}", selected_mechanism); - let mut data: Option> = None; - if !session.are_we_first() { - // if not first mention the mechanism then get challenge data - // mention mechanism - let auth = Auth { - mechanism: selected_mechanism.as_str(), - sasl_data: "=", - }; - Into::::into(auth).write(&mut self.writer).await?; - // get challenge data - let challenge = &Element::read(&mut self.reader).await?; - let challenge: Challenge = challenge.try_into()?; - println!("challenge: {:?}", challenge); - data = Some(challenge.sasl_data.to_owned()); - println!("we didn't go first"); - } else { - // if first, mention mechanism and send data - let mut sasl_data = Vec::new(); - session.step64(None, &mut sasl_data).unwrap(); - let auth = Auth { - mechanism: selected_mechanism.as_str(), - sasl_data: str::from_utf8(&sasl_data)?, - }; - println!("{:?}", auth); - Into::::into(auth).write(&mut self.writer).await?; - - let server_response = Element::read(&mut self.reader).await?; - println!("server_response: {:#?}", server_response); - match TryInto::::try_into(&server_response) { - Ok(challenge) => data = Some(challenge.sasl_data.to_owned()), - Err(_) => { - let success = TryInto::::try_into(&server_response)?; - if let Some(sasl_data) = success.sasl_data { - data = Some(sasl_data.to_owned()) - } - } - } - println!("we went first"); - } - - // stepping the authentication exchange to completion - if data != None { - println!("data: {:?}", data); - let mut sasl_data = Vec::new(); - while { - // decide if need to send more data over - let state = session - .step64(data.as_deref(), &mut sasl_data) - .expect("step errored!"); - state.is_running() - } { - // While we aren't finished, receive more data from the other party - let response = Response { - sasl_data: str::from_utf8(&sasl_data)?, - }; - println!("response: {:?}", response); - Into::::into(response) - .write(&mut self.writer) - .await?; - - let server_response = Element::read(&mut self.reader).await?; - println!("server_response: {:?}", server_response); - match TryInto::::try_into(&server_response) { - Ok(challenge) => data = Some(challenge.sasl_data.to_owned()), - Err(_) => { - let success = TryInto::::try_into(&server_response)?; - if let Some(sasl_data) = success.sasl_data { - data = Some(sasl_data.to_owned()) - } - } - } - } - } - self.start_stream().await?; - Ok(()) - } - - pub async fn bind(&mut self) -> Result<()> { - match &self.jabber.jid.resourcepart { - Some(resource) => { - println!("setting resource"); - let bind = Bind { - resource: Some(resource.clone()), - jid: None, - }; - let result: Bind = IQ::set(self, None, None, bind).await?.try_into()?; - if let Some(jid) = result.jid { - println!("{}", jid); - self.jabber.jid = jid; - return Ok(()); - } - } - None => { - println!("not setting resource"); - let bind = Bind { - resource: None, - jid: None, - }; - let result: Bind = IQ::set(self, None, None, bind).await?.try_into()?; - if let Some(jid) = result.jid { - println!("{}", jid); - self.jabber.jid = jid; - return Ok(()); - } - } - } - Err(JabberError::BindError) - } -} -- cgit