summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@blos.sm>2023-07-11 21:28:42 +0100
committerLibravatar cel 🌸 <cel@blos.sm>2023-07-11 21:28:42 +0100
commitf43911ccbae3856b35b0d3e8ec6ac6450e295da6 (patch)
tree492b195cc06b08e546c059c16a748f369995eab1 /src/client
parent143a0365d0822e6786cdac3530a725bbf450f38f (diff)
downloadluz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.tar.gz
luz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.tar.bz2
luz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.zip
remove serde functions
Diffstat (limited to '')
-rw-r--r--src/client/encrypted.rs216
-rw-r--r--src/client/mod.rs17
-rw-r--r--src/client/unencrypted.rs76
3 files changed, 61 insertions, 248 deletions
diff --git a/src/client/encrypted.rs b/src/client/encrypted.rs
index a4bf0d1..76f600c 100644
--- a/src/client/encrypted.rs
+++ b/src/client/encrypted.rs
@@ -1,35 +1,26 @@
-use std::str;
-
use quick_xml::{
- de::Deserializer,
- events::{BytesDecl, BytesStart, Event},
- name::QName,
- se::Serializer,
+ events::{BytesDecl, Event},
Reader, Writer,
};
-use rsasl::prelude::{Mechname, SASLClient};
-use serde::{Deserialize, Serialize};
-use tokio::io::{AsyncWriteExt, BufReader, ReadHalf, WriteHalf};
+use tokio::io::{BufReader, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio_native_tls::TlsStream;
-use crate::stanza::{
- sasl::{Auth, Challenge, Mechanisms},
- stream::{StreamFeature, StreamFeatures},
-};
+use crate::element::Element;
+use crate::stanza::stream::{Stream, StreamFeature};
use crate::Jabber;
use crate::Result;
pub struct JabberClient<'j> {
reader: Reader<BufReader<ReadHalf<TlsStream<TcpStream>>>>,
- writer: WriteHalf<TlsStream<TcpStream>>,
+ writer: Writer<WriteHalf<TlsStream<TcpStream>>>,
jabber: &'j mut Jabber<'j>,
}
impl<'j> JabberClient<'j> {
pub fn new(
reader: Reader<BufReader<ReadHalf<TlsStream<TcpStream>>>>,
- writer: WriteHalf<TlsStream<TcpStream>>,
+ writer: Writer<WriteHalf<TlsStream<TcpStream>>>,
jabber: &'j mut Jabber<'j>,
) -> Self {
Self {
@@ -40,90 +31,29 @@ impl<'j> JabberClient<'j> {
}
pub async fn start_stream(&mut self) -> Result<()> {
+ // client to server
let declaration = BytesDecl::new("1.0", None, None);
- let mut stream_element = BytesStart::new("stream:stream");
- stream_element.push_attribute(("from".as_bytes(), self.jabber.jid.to_string().as_bytes()));
- stream_element.push_attribute(("to".as_bytes(), self.jabber.server.as_bytes()));
- stream_element.push_attribute(("version", "1.0"));
- stream_element.push_attribute(("xml:lang", "en"));
- stream_element.push_attribute(("xmlns", "jabber:client"));
- stream_element.push_attribute(("xmlns:stream", "http://etherx.jabber.org/streams"));
- let mut writer = Writer::new(&mut self.writer);
- writer.write_event_async(Event::Decl(declaration)).await;
- writer.write_event_async(Event::Start(stream_element)).await;
+ 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).await?;
+ // server to client
let mut buf = Vec::new();
- loop {
- match self.reader.read_event_into_async(&mut buf).await.unwrap() {
- Event::Start(e) => {
- println!("{:?}", e);
- break;
- }
- e => println!("decl: {:?}", e),
- };
- }
+ self.reader.read_event_into_async(&mut buf).await?;
+ let _stream_response = Element::read_start(&mut self.reader).await?;
Ok(())
}
- pub async fn get_node<'a>(&mut self) -> Result<String> {
- let mut buf = Vec::new();
- let mut txt = Vec::new();
- let mut qname_set = false;
- let mut qname: Option<Vec<u8>> = None;
- loop {
- match self.reader.read_event_into_async(&mut buf).await? {
- Event::Start(e) => {
- if !qname_set {
- qname = Some(e.name().into_inner().to_owned());
- qname_set = true;
- }
- txt.push(b'<');
- txt = txt
- .into_iter()
- .chain(buf.to_owned())
- .chain(vec![b'>'])
- .collect();
- }
- Event::End(e) => {
- let mut end = false;
- if e.name() == QName(qname.as_deref().unwrap()) {
- end = true;
- }
- txt.push(b'<');
- txt = txt
- .into_iter()
- .chain(buf.to_owned())
- .chain(vec![b'>'])
- .collect();
- if end {
- break;
- }
- }
- Event::Text(_e) => {
- txt = txt.into_iter().chain(buf.to_owned()).collect();
- }
- _ => {
- txt.push(b'<');
- txt = txt
- .into_iter()
- .chain(buf.to_owned())
- .chain(vec![b'>'])
- .collect();
- }
- }
- buf.clear();
+ pub async fn get_features(&mut self) -> Result<Option<Vec<StreamFeature>>> {
+ if let Some(features) = Element::read(&mut self.reader).await? {
+ Ok(Some(features.try_into()?))
+ } else {
+ Ok(None)
}
- println!("{:?}", txt);
- let decoded = str::from_utf8(&txt)?.to_owned();
- println!("{:?}", decoded);
- Ok(decoded)
- }
-
- pub async fn get_features(&mut self) -> Result<Vec<StreamFeature>> {
- let node = self.get_node().await?;
- let mut deserializer = Deserializer::from_str(&node);
- let features = StreamFeatures::deserialize(&mut deserializer).unwrap();
- println!("{:?}", features);
- Ok(features.features)
}
pub async fn negotiate(&mut self) -> Result<()> {
@@ -131,98 +61,14 @@ impl<'j> JabberClient<'j> {
println!("loop");
let features = &self.get_features().await?;
println!("{:?}", features);
- match &features[0] {
- StreamFeature::Sasl(sasl) => {
- println!("{:?}", sasl);
- self.sasl(&sasl).await?;
- }
- StreamFeature::Bind => todo!(),
- x => println!("{:?}", x),
- }
+ // match &features[0] {
+ // StreamFeature::Sasl(sasl) => {
+ // println!("{:?}", sasl);
+ // todo!()
+ // }
+ // StreamFeature::Bind => todo!(),
+ // x => println!("{:?}", x),
+ // }
}
}
-
- pub async fn sasl(&mut self, mechanisms: &Mechanisms) -> Result<()> {
- println!("{:?}", mechanisms);
- let sasl = SASLClient::new(self.jabber.auth.clone());
- let mut offered_mechs: Vec<&Mechname> = Vec::new();
- for mechanism in &mechanisms.mechanisms {
- offered_mechs.push(Mechname::parse(&mechanism.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 {
- ns: "urn:ietf:params:xml:ns:xmpp-sasl".to_owned(),
- mechanism: selected_mechanism.clone(),
- sasl_data: Some("=".to_owned()),
- };
- let mut buffer = String::new();
- let ser = Serializer::new(&mut buffer);
- auth.serialize(ser).unwrap();
- self.writer.write_all(buffer.as_bytes());
- // get challenge data
- let node = self.get_node().await?;
- let mut deserializer = Deserializer::from_str(&node);
- let challenge = Challenge::deserialize(&mut deserializer).unwrap();
- println!("challenge: {:?}", challenge);
- data = Some(challenge.sasl_data.as_bytes().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 {
- ns: "urn:ietf:params:xml:ns:xmpp-sasl".to_owned(),
- mechanism: selected_mechanism.clone(),
- sasl_data: Some(str::from_utf8(&sasl_data).unwrap().to_owned()),
- };
- let mut buffer = String::new();
- let ser = Serializer::new(&mut buffer);
- auth.serialize(ser).unwrap();
- println!("node: {:?}", buffer);
- self.writer.write_all(buffer.as_bytes()).await;
- println!("we went first");
- // get challenge data
- // TODO: check if needed
- // let node = self.get_node().await?;
- // println!("node: {:?}", node);
- // let mut deserializer = Deserializer::from_str(&node);
- // let challenge = Challenge::deserialize(&mut deserializer).unwrap();
- // println!("challenge: {:?}", challenge);
- // data = Some(challenge.sasl_data.as_bytes().to_owned());
- }
-
- // stepping the authentication exchange to completion
- 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 auth = Auth {
- ns: "urn:ietf:params:xml:ns:xmpp-sasl".to_owned(),
- mechanism: selected_mechanism.clone(),
- sasl_data: Some(str::from_utf8(&sasl_data).unwrap().to_owned()),
- };
- let mut buffer = String::new();
- let ser = Serializer::new(&mut buffer);
- auth.serialize(ser).unwrap();
- self.writer.write_all(buffer.as_bytes());
- let node = self.get_node().await?;
- let mut deserializer = Deserializer::from_str(&node);
- let challenge = Challenge::deserialize(&mut deserializer).unwrap();
- data = Some(challenge.sasl_data.as_bytes().to_owned());
- }
- self.start_stream().await?;
- Ok(())
- }
}
diff --git a/src/client/mod.rs b/src/client/mod.rs
index fe3dd34..d545923 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -15,17 +15,16 @@ pub enum JabberClientType<'j> {
impl<'j> JabberClientType<'j> {
pub async fn ensure_tls(self) -> Result<encrypted::JabberClient<'j>> {
match self {
- Self::Encrypted(mut c) => {
- c.start_stream();
- Ok(c)
- }
+ Self::Encrypted(c) => Ok(c),
Self::Unencrypted(mut c) => {
- c.start_stream().await?;
- let features = c.get_features().await?;
- if features.contains(&StreamFeature::StartTls) {
- Ok(c.starttls().await?)
+ if let Some(features) = c.get_features().await? {
+ if features.contains(&StreamFeature::StartTls) {
+ Ok(c.starttls().await?)
+ } else {
+ Err(JabberError::StartTlsUnavailable)
+ }
} else {
- Err(JabberError::StartTlsUnavailable)
+ Err(JabberError::NoFeatures)
}
}
}
diff --git a/src/client/unencrypted.rs b/src/client/unencrypted.rs
index d4225d3..ce534c7 100644
--- a/src/client/unencrypted.rs
+++ b/src/client/unencrypted.rs
@@ -1,19 +1,19 @@
use std::str;
use quick_xml::{
- de::Deserializer,
events::{BytesDecl, BytesStart, Event},
name::QName,
Reader, Writer,
};
-use serde::Deserialize;
use tokio::io::{BufReader, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio_native_tls::native_tls::TlsConnector;
+use crate::element::Element;
+use crate::stanza::stream::StreamFeature;
+use crate::Jabber;
use crate::Result;
-use crate::{error::JabberError, stanza::stream::StreamFeature};
-use crate::{stanza::stream::StreamFeatures, Jabber};
+use crate::{error::JabberError, stanza::stream::Stream};
pub struct JabberClient<'j> {
reader: Reader<BufReader<ReadHalf<TcpStream>>>,
@@ -35,63 +35,30 @@ impl<'j> JabberClient<'j> {
}
pub async fn start_stream(&mut self) -> Result<()> {
+ // client to server
let declaration = BytesDecl::new("1.0", None, None);
- let mut stream_element = BytesStart::new("stream:stream");
- stream_element.push_attribute(("from".as_bytes(), self.jabber.jid.to_string().as_bytes()));
- stream_element.push_attribute(("to".as_bytes(), self.jabber.server.as_bytes()));
- stream_element.push_attribute(("version", "1.0"));
- stream_element.push_attribute(("xml:lang", "en"));
- stream_element.push_attribute(("xmlns", "jabber:client"));
- stream_element.push_attribute(("xmlns:stream", "http://etherx.jabber.org/streams"));
+ 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;
- self.writer
- .write_event_async(Event::Start(stream_element))
- .await
- .unwrap();
+ .await?;
+ let stream_element: Element<'_> = stream_element.into();
+ stream_element.write_start(&mut self.writer).await?;
+ // server to client
let mut buf = Vec::new();
- loop {
- match self.reader.read_event_into_async(&mut buf).await.unwrap() {
- Event::Start(e) => {
- println!("{:?}", e);
- break;
- }
- Event::Decl(e) => println!("decl: {:?}", e),
- _ => return Err(JabberError::BadStream),
- }
- }
+ 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>> {
- let mut buf = Vec::new();
- let mut txt = Vec::new();
- let mut loop_end = false;
- while !loop_end {
- match self.reader.read_event_into_async(&mut buf).await.unwrap() {
- Event::End(e) => {
- if e.name() == QName(b"stream:features") {
- loop_end = true;
- }
- }
- _ => (),
- }
- txt.push(b'<');
- txt = txt
- .into_iter()
- .chain(buf.to_owned())
- .chain(vec![b'>'])
- .collect();
- buf.clear();
+ pub async fn get_features(&mut self) -> Result<Option<Vec<StreamFeature>>> {
+ if let Some(features) = Element::read(&mut self.reader).await? {
+ println!("{:?}", features);
+ Ok(Some(features.try_into()?))
+ } else {
+ Ok(None)
}
- println!("{:?}", txt);
- let decoded = str::from_utf8(&txt).unwrap();
- println!("decoded: {:?}", decoded);
- let mut deserializer = Deserializer::from_str(decoded);
- let features = StreamFeatures::deserialize(&mut deserializer).unwrap();
- println!("{:?}", features);
- Ok(features.features)
}
pub async fn starttls(mut self) -> Result<super::encrypted::JabberClient<'j>> {
@@ -115,8 +82,9 @@ impl<'j> JabberClient<'j> {
.connect(&self.jabber.server, stream)
.await
{
- let (read, writer) = tokio::io::split(tlsstream);
+ let (read, write) = tokio::io::split(tlsstream);
let reader = Reader::from_reader(BufReader::new(read));
+ let writer = Writer::new(write);
let mut client =
super::encrypted::JabberClient::new(reader, writer, self.jabber);
client.start_stream().await?;