summaryrefslogtreecommitdiffstats
path: root/src/client/encrypted.rs
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@blos.sm>2023-10-21 01:28:54 +0100
committerLibravatar cel 🌸 <cel@blos.sm>2023-10-21 01:28:54 +0100
commite893869df974ebb7afcc318119840c53f8f377cb (patch)
tree3319dba477784c126011acc5422c9973782f7850 /src/client/encrypted.rs
parentba94ee66fafbabd63d6d1ed5edf435d4c46c6796 (diff)
downloadluz-e893869df974ebb7afcc318119840c53f8f377cb.tar.gz
luz-e893869df974ebb7afcc318119840c53f8f377cb.tar.bz2
luz-e893869df974ebb7afcc318119840c53f8f377cb.zip
implement connection
Diffstat (limited to 'src/client/encrypted.rs')
-rw-r--r--src/client/encrypted.rs205
1 files changed, 0 insertions, 205 deletions
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<BufReader<ReadHalf<TlsStream<TcpStream>>>>,
- pub writer: Writer<WriteHalf<TlsStream<TcpStream>>>,
- jabber: &'j mut Jabber<'j>,
-}
-
-impl<'j> JabberClient<'j> {
- pub fn new(
- reader: NsReader<BufReader<ReadHalf<TlsStream<TcpStream>>>>,
- writer: Writer<WriteHalf<TlsStream<TcpStream>>>,
- 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<Vec<StreamFeature>> {
- 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<String>) -> 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<Vec<u8>> = 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::<Element>::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::<Element>::into(auth).write(&mut self.writer).await?;
-
- let server_response = Element::read(&mut self.reader).await?;
- println!("server_response: {:#?}", server_response);
- match TryInto::<Challenge>::try_into(&server_response) {
- Ok(challenge) => data = Some(challenge.sasl_data.to_owned()),
- Err(_) => {
- let success = TryInto::<Success>::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::<Element>::into(response)
- .write(&mut self.writer)
- .await?;
-
- let server_response = Element::read(&mut self.reader).await?;
- println!("server_response: {:?}", server_response);
- match TryInto::<Challenge>::try_into(&server_response) {
- Ok(challenge) => data = Some(challenge.sasl_data.to_owned()),
- Err(_) => {
- let success = TryInto::<Success>::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)
- }
-}