2020-03-05 01:25:24 +01:00
|
|
|
use futures::{sink::SinkExt, stream::StreamExt};
|
2021-02-15 20:45:58 +01:00
|
|
|
|
2023-10-24 18:24:04 +02:00
|
|
|
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
|
2021-02-15 20:45:58 +01:00
|
|
|
use {
|
2021-12-01 16:24:28 +01:00
|
|
|
std::convert::TryFrom,
|
2021-02-15 20:45:58 +01:00
|
|
|
std::sync::Arc,
|
2021-12-01 16:24:28 +01:00
|
|
|
tokio_rustls::{
|
|
|
|
|
client::TlsStream,
|
|
|
|
|
rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore, ServerName},
|
|
|
|
|
TlsConnector,
|
|
|
|
|
},
|
2021-02-15 20:45:58 +01:00
|
|
|
webpki_roots,
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-15 19:59:46 +01:00
|
|
|
#[cfg(feature = "tls-native")]
|
2021-02-15 20:45:58 +01:00
|
|
|
use {
|
|
|
|
|
native_tls::TlsConnector as NativeTlsConnector,
|
|
|
|
|
tokio_native_tls::{TlsConnector, TlsStream},
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-05 01:25:24 +01:00
|
|
|
use tokio::io::{AsyncRead, AsyncWrite};
|
2020-05-30 01:19:06 +02:00
|
|
|
use xmpp_parsers::{ns, Element};
|
2017-06-05 00:42:35 +02:00
|
|
|
|
2018-12-18 18:29:31 +01:00
|
|
|
use crate::xmpp_codec::Packet;
|
|
|
|
|
use crate::xmpp_stream::XMPPStream;
|
2020-03-05 01:25:24 +01:00
|
|
|
use crate::{Error, ProtocolError};
|
2017-06-05 00:42:35 +02:00
|
|
|
|
2021-02-15 19:59:46 +01:00
|
|
|
#[cfg(feature = "tls-native")]
|
|
|
|
|
async fn get_tls_stream<S: AsyncRead + AsyncWrite + Unpin>(
|
|
|
|
|
xmpp_stream: XMPPStream<S>,
|
|
|
|
|
) -> Result<TlsStream<S>, Error> {
|
2023-06-21 18:30:25 +02:00
|
|
|
let domain = xmpp_stream.jid.domain_str().to_owned();
|
2021-02-15 19:59:46 +01:00
|
|
|
let stream = xmpp_stream.into_inner();
|
|
|
|
|
let tls_stream = TlsConnector::from(NativeTlsConnector::builder().build().unwrap())
|
|
|
|
|
.connect(&domain, stream)
|
|
|
|
|
.await?;
|
|
|
|
|
Ok(tls_stream)
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 18:24:04 +02:00
|
|
|
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
|
2021-02-15 19:59:46 +01:00
|
|
|
async fn get_tls_stream<S: AsyncRead + AsyncWrite + Unpin>(
|
|
|
|
|
xmpp_stream: XMPPStream<S>,
|
|
|
|
|
) -> Result<TlsStream<S>, Error> {
|
2023-06-20 14:35:28 +02:00
|
|
|
let domain = xmpp_stream.jid.domain().to_owned();
|
2021-12-01 17:30:20 +01:00
|
|
|
let domain = ServerName::try_from(domain.as_str())?;
|
2021-02-15 19:59:46 +01:00
|
|
|
let stream = xmpp_stream.into_inner();
|
2021-12-01 16:24:28 +01:00
|
|
|
let mut root_store = RootCertStore::empty();
|
2023-10-24 18:34:24 +02:00
|
|
|
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
|
2021-12-01 16:24:28 +01:00
|
|
|
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
|
|
|
|
ta.subject,
|
|
|
|
|
ta.spki,
|
|
|
|
|
ta.name_constraints,
|
|
|
|
|
)
|
|
|
|
|
}));
|
|
|
|
|
let config = ClientConfig::builder()
|
|
|
|
|
.with_safe_defaults()
|
|
|
|
|
.with_root_certificates(root_store)
|
|
|
|
|
.with_no_client_auth();
|
2021-02-15 20:45:58 +01:00
|
|
|
let tls_stream = TlsConnector::from(Arc::new(config))
|
2021-02-15 19:59:46 +01:00
|
|
|
.connect(domain, stream)
|
|
|
|
|
.await?;
|
|
|
|
|
Ok(tls_stream)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-16 00:34:46 +01:00
|
|
|
/// Performs `<starttls/>` on an XMPPStream and returns a binary
|
|
|
|
|
/// TlsStream.
|
2020-03-05 01:25:24 +01:00
|
|
|
pub async fn starttls<S: AsyncRead + AsyncWrite + Unpin>(
|
|
|
|
|
mut xmpp_stream: XMPPStream<S>,
|
|
|
|
|
) -> Result<TlsStream<S>, Error> {
|
2020-05-30 01:19:06 +02:00
|
|
|
let nonza = Element::builder("starttls", ns::TLS).build();
|
2020-03-05 01:25:24 +01:00
|
|
|
let packet = Packet::Stanza(nonza);
|
|
|
|
|
xmpp_stream.send(packet).await?;
|
|
|
|
|
|
|
|
|
|
loop {
|
|
|
|
|
match xmpp_stream.next().await {
|
|
|
|
|
Some(Ok(Packet::Stanza(ref stanza))) if stanza.name() == "proceed" => break,
|
|
|
|
|
Some(Ok(Packet::Text(_))) => {}
|
|
|
|
|
Some(Err(e)) => return Err(e.into()),
|
|
|
|
|
_ => {
|
|
|
|
|
return Err(ProtocolError::NoTls.into());
|
|
|
|
|
}
|
2017-06-05 00:42:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-09-01 22:59:02 +03:00
|
|
|
|
2021-02-15 19:59:46 +01:00
|
|
|
get_tls_stream(xmpp_stream).await
|
2017-06-05 00:42:35 +02:00
|
|
|
}
|