luz/src/jabber.rs

165 lines
5.0 KiB
Rust
Raw Normal View History

2023-10-28 21:06:42 +01:00
use std::str;
2023-07-04 21:27:15 +01:00
use std::sync::Arc;
2023-06-19 19:23:54 +01:00
2024-11-23 22:39:44 +00:00
use peanuts::{Reader, Writer};
2023-07-04 21:27:15 +01:00
use rsasl::prelude::SASLConfig;
2023-10-21 01:28:54 +01:00
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader, ReadHalf, WriteHalf};
2023-10-28 21:06:42 +01:00
use tracing::{debug, info, trace};
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
use crate::connection::{Tls, Unencrypted};
2024-11-23 22:39:44 +00:00
use crate::error::Error;
2023-10-21 01:28:54 +01:00
use crate::stanza::stream::Stream;
2024-11-23 22:39:44 +00:00
use crate::stanza::XML_VERSION;
2023-10-21 01:28:54 +01:00
use crate::Result;
use crate::JID;
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
pub struct Jabber<S>
where
S: AsyncRead + AsyncWrite + Unpin,
{
2024-11-23 22:39:44 +00:00
reader: Reader<ReadHalf<S>>,
writer: Writer<WriteHalf<S>>,
2023-10-21 01:28:54 +01:00
jid: Option<JID>,
auth: Option<Arc<SASLConfig>>,
server: String,
2023-06-19 19:23:54 +01:00
}
2023-10-21 01:28:54 +01:00
impl<S> Jabber<S>
where
S: AsyncRead + AsyncWrite + Unpin,
{
pub fn new(
reader: ReadHalf<S>,
writer: WriteHalf<S>,
jid: Option<JID>,
auth: Option<Arc<SASLConfig>>,
server: String,
) -> Self {
2024-11-23 22:39:44 +00:00
let reader = Reader::new(reader);
let writer = Writer::new(writer);
2023-10-21 01:28:54 +01:00
Self {
reader,
writer,
2023-06-19 19:23:54 +01:00
jid,
2023-07-04 21:27:15 +01:00
auth,
2023-06-19 19:23:54 +01:00
server,
2023-10-21 01:28:54 +01:00
}
2023-06-19 19:23:54 +01:00
}
2023-10-21 01:28:54 +01:00
}
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
impl<S> Jabber<S>
where
2024-11-23 22:39:44 +00:00
S: AsyncRead + AsyncWrite + Unpin + Send,
2023-10-21 01:28:54 +01:00
{
2023-10-28 21:06:42 +01:00
// pub async fn negotiate(self) -> Result<Jabber<S>> {}
2023-10-21 01:28:54 +01:00
pub async fn start_stream(&mut self) -> Result<()> {
// client to server
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
// declaration
2024-11-23 22:39:44 +00:00
self.writer.write_declaration(XML_VERSION).await?;
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
// opening stream element
2024-11-23 22:39:44 +00:00
let server = self.server.clone().try_into()?;
let stream = Stream::new_client(None, server, None, "en".to_string());
2023-10-21 01:28:54 +01:00
// TODO: nicer function to serialize to xml writer
2024-11-23 22:39:44 +00:00
self.writer.write_start(&stream).await?;
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
// server to client
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
// may or may not send a declaration
2024-11-23 22:39:44 +00:00
let decl = self.reader.read_prolog().await?;
2023-06-19 19:23:54 +01:00
2023-10-21 01:28:54 +01:00
// receive stream element and validate
2024-11-23 22:39:44 +00:00
let stream: Stream = self.reader.read_start().await?;
if let Some(from) = stream.from {
self.server = from.to_string()
2023-06-19 19:23:54 +01:00
}
2024-11-23 22:39:44 +00:00
Ok(())
2023-06-19 19:23:54 +01:00
}
}
2023-10-21 01:28:54 +01:00
// pub async fn get_features(&mut self) -> Result<Vec<StreamFeature>> {
// Element::read(&mut self.reader).await?.try_into()
// }
impl Jabber<Unencrypted> {
2023-10-28 21:06:42 +01:00
pub async fn starttls(&mut self) -> Result<Jabber<Tls>> {
2023-10-21 01:28:54 +01:00
todo!()
}
// let mut starttls_element = BytesStart::new("starttls");
// starttls_element.push_attribute(("xmlns", "urn:ietf:params:xml:ns:xmpp-tls"));
// self.writer
// .write_event_async(Event::Empty(starttls_element))
// .await
// .unwrap();
// let mut buf = Vec::new();
// match self.reader.read_event_into_async(&mut buf).await.unwrap() {
// Event::Empty(e) => match e.name() {
// QName(b"proceed") => {
// let connector = TlsConnector::new().unwrap();
// let stream = self
// .reader
// .into_inner()
// .into_inner()
// .unsplit(self.writer.into_inner());
// if let Ok(tlsstream) = tokio_native_tls::TlsConnector::from(connector)
// .connect(&self.jabber.server, stream)
// .await
// {
// 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?;
// return Ok(client);
// }
// }
// QName(_) => return Err(JabberError::TlsNegotiation),
// },
// _ => return Err(JabberError::TlsNegotiation),
// }
// Err(JabberError::TlsNegotiation)
// }
}
2023-10-28 21:06:42 +01:00
impl std::fmt::Debug for Jabber<Tls> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Jabber")
.field("connection", &"tls")
.field("jid", &self.jid)
.field("auth", &self.auth)
.field("server", &self.server)
.finish()
}
}
impl std::fmt::Debug for Jabber<Unencrypted> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Jabber")
.field("connection", &"unencrypted")
.field("jid", &self.jid)
.field("auth", &self.auth)
.field("server", &self.server)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::connection::Connection;
use test_log::test;
#[test(tokio::test)]
async fn start_stream() {
let connection = Connection::connect("blos.sm").await.unwrap();
match connection {
Connection::Encrypted(mut c) => c.start_stream().await.unwrap(),
Connection::Unencrypted(mut c) => c.start_stream().await.unwrap(),
}
}
}