mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
Add disabled-by-default insecure-tcp feature to tokio-xmpp for use by component connections
This commit is contained in:
parent
38bfba4a18
commit
019450ff4b
9 changed files with 112 additions and 12 deletions
|
@ -36,6 +36,8 @@ tokio-rustls = { version = "0.24", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = { version = "0.10", default-features = false, features = ["auto-color", "humantime"] }
|
env_logger = { version = "0.10", default-features = false, features = ["auto-color", "humantime"] }
|
||||||
|
# this is needed for echo-component example
|
||||||
|
tokio-xmpp = { path = ".", features = ["insecure-tcp"]}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["starttls-rust"]
|
default = ["starttls-rust"]
|
||||||
|
@ -44,4 +46,5 @@ tls-rust = ["tokio-rustls", "webpki-roots"]
|
||||||
tls-native = ["tokio-native-tls", "native-tls"]
|
tls-native = ["tokio-native-tls", "native-tls"]
|
||||||
starttls-native = ["starttls", "tls-native"]
|
starttls-native = ["starttls", "tls-native"]
|
||||||
starttls-rust = ["starttls", "tls-rust"]
|
starttls-rust = ["starttls", "tls-rust"]
|
||||||
|
insecure-tcp = []
|
||||||
syntax-highlighting = ["syntect"]
|
syntax-highlighting = ["syntect"]
|
||||||
|
|
|
@ -2,7 +2,7 @@ use futures::stream::StreamExt;
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio_xmpp::Component;
|
use tokio_xmpp::tcp::TcpComponent as Component;
|
||||||
use xmpp_parsers::message::{Body, Message, MessageType};
|
use xmpp_parsers::message::{Body, Message, MessageType};
|
||||||
use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType};
|
use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType};
|
||||||
use xmpp_parsers::{Element, Jid};
|
use xmpp_parsers::{Element, Jid};
|
||||||
|
@ -12,22 +12,21 @@ async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let args: Vec<String> = args().collect();
|
let args: Vec<String> = args().collect();
|
||||||
if args.len() < 3 || args.len() > 5 {
|
if args.len() < 3 || args.len() > 4 {
|
||||||
println!("Usage: {} <jid> <password> [server] [port]", args[0]);
|
println!("Usage: {} <jid> <password> [server:port]", args[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
let jid = &args[1];
|
let jid = &args[1];
|
||||||
let password = &args[2];
|
let password = &args[2];
|
||||||
let server = &args
|
let server = args
|
||||||
.get(3)
|
.get(3)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap_or("127.0.0.1".to_owned());
|
.unwrap_or("127.0.0.1:5347".to_owned());
|
||||||
let port: u16 = args.get(4).unwrap().parse().unwrap_or(5347u16);
|
|
||||||
|
|
||||||
// Component instance
|
// Component instance
|
||||||
println!("{} {} {} {}", jid, password, server, port);
|
println!("{} {} {}", jid, password, server);
|
||||||
let mut component = Component::new(jid, password, server, port).await.unwrap();
|
let mut component = Component::new(jid, password, server).await.unwrap();
|
||||||
|
|
||||||
// Make the two interfaces for sending and receiving independent
|
// Make the two interfaces for sending and receiving independent
|
||||||
// of each other so we can move one into a closure.
|
// of each other so we can move one into a closure.
|
||||||
|
|
|
@ -31,7 +31,11 @@ pub struct Component<C: ServerConnector> {
|
||||||
|
|
||||||
impl<C: ServerConnector> Component<C> {
|
impl<C: ServerConnector> Component<C> {
|
||||||
/// Start a new XMPP component
|
/// Start a new XMPP component
|
||||||
pub async fn new(jid: &str, password: &str, connector: C) -> Result<Self, Error> {
|
pub async fn new_with_connector(
|
||||||
|
jid: &str,
|
||||||
|
password: &str,
|
||||||
|
connector: C,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let jid = Jid::from_str(jid)?;
|
let jid = Jid::from_str(jid)?;
|
||||||
let password = password.to_owned();
|
let password = password.to_owned();
|
||||||
let stream = component_login(connector, jid.clone(), password).await?;
|
let stream = component_login(connector, jid.clone(), password).await?;
|
||||||
|
|
|
@ -17,6 +17,8 @@ compile_error!(
|
||||||
#[cfg(feature = "starttls")]
|
#[cfg(feature = "starttls")]
|
||||||
pub mod starttls;
|
pub mod starttls;
|
||||||
mod stream_start;
|
mod stream_start;
|
||||||
|
#[cfg(feature = "insecure-tcp")]
|
||||||
|
pub mod tcp;
|
||||||
mod xmpp_codec;
|
mod xmpp_codec;
|
||||||
pub use crate::xmpp_codec::Packet;
|
pub use crate::xmpp_codec::Packet;
|
||||||
mod event;
|
mod event;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! StartTLS ServerConnector Error
|
||||||
|
|
||||||
use hickory_resolver::{error::ResolveError, proto::error::ProtoError};
|
use hickory_resolver::{error::ResolveError, proto::error::ProtoError};
|
||||||
#[cfg(feature = "tls-native")]
|
#[cfg(feature = "tls-native")]
|
||||||
use native_tls::Error as TlsError;
|
use native_tls::Error as TlsError;
|
||||||
|
@ -9,7 +11,7 @@ use tokio_rustls::rustls::client::InvalidDnsNameError;
|
||||||
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
|
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
|
||||||
use tokio_rustls::rustls::Error as TlsError;
|
use tokio_rustls::rustls::Error as TlsError;
|
||||||
|
|
||||||
/// Top-level error type
|
/// StartTLS ServerConnector Error
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Error resolving DNS and establishing a connection
|
/// Error resolving DNS and establishing a connection
|
||||||
|
|
|
@ -26,16 +26,21 @@ use tokio::{
|
||||||
};
|
};
|
||||||
use xmpp_parsers::{ns, Element, Jid};
|
use xmpp_parsers::{ns, Element, Jid};
|
||||||
|
|
||||||
use crate::{connect::ServerConnector, xmpp_codec::Packet};
|
use crate::{connect::ServerConnector, xmpp_codec::Packet, AsyncClient, SimpleClient};
|
||||||
use crate::{connect::ServerConnectorError, xmpp_stream::XMPPStream};
|
use crate::{connect::ServerConnectorError, xmpp_stream::XMPPStream};
|
||||||
|
|
||||||
use self::error::Error;
|
use self::error::Error;
|
||||||
use self::happy_eyeballs::{connect_to_host, connect_with_srv};
|
use self::happy_eyeballs::{connect_to_host, connect_with_srv};
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
mod error;
|
pub mod error;
|
||||||
mod happy_eyeballs;
|
mod happy_eyeballs;
|
||||||
|
|
||||||
|
/// AsyncClient that connects over StartTls
|
||||||
|
pub type StartTlsAsyncClient = AsyncClient<ServerConfig>;
|
||||||
|
/// SimpleClient that connects over StartTls
|
||||||
|
pub type StartTlsSimpleClient = SimpleClient<ServerConfig>;
|
||||||
|
|
||||||
/// StartTLS XMPP server connection configuration
|
/// StartTLS XMPP server connection configuration
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ServerConfig {
|
pub enum ServerConfig {
|
||||||
|
|
10
tokio-xmpp/src/tcp/component.rs
Normal file
10
tokio-xmpp/src/tcp/component.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use crate::{Component, Error};
|
||||||
|
|
||||||
|
use super::TcpServerConnector;
|
||||||
|
|
||||||
|
impl Component<TcpServerConnector> {
|
||||||
|
/// Start a new XMPP component
|
||||||
|
pub async fn new(jid: &str, password: &str, server: String) -> Result<Self, Error> {
|
||||||
|
Self::new_with_connector(jid, password, TcpServerConnector::new(server)).await
|
||||||
|
}
|
||||||
|
}
|
26
tokio-xmpp/src/tcp/error.rs
Normal file
26
tokio-xmpp/src/tcp/error.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//! TCP ServerConnector Error
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
/// TCP ServerConnector Error
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// tokio-xmpp error
|
||||||
|
TokioXMPP(crate::error::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::TokioXMPP(e) => write!(fmt, "TokioXMPP error: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::error::Error> for Error {
|
||||||
|
fn from(e: crate::error::Error) -> Self {
|
||||||
|
Error::TokioXMPP(e)
|
||||||
|
}
|
||||||
|
}
|
49
tokio-xmpp/src/tcp/mod.rs
Normal file
49
tokio-xmpp/src/tcp/mod.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//! `starttls::ServerConfig` provides a `ServerConnector` for starttls connections
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
connect::{ServerConnector, ServerConnectorError},
|
||||||
|
xmpp_stream::XMPPStream,
|
||||||
|
Component,
|
||||||
|
};
|
||||||
|
|
||||||
|
use self::error::Error;
|
||||||
|
|
||||||
|
mod component;
|
||||||
|
pub mod error;
|
||||||
|
|
||||||
|
/// Component that connects over TCP
|
||||||
|
pub type TcpComponent = Component<TcpServerConnector>;
|
||||||
|
|
||||||
|
/// Connect via insecure plaintext TCP to an XMPP server
|
||||||
|
/// This should only be used over localhost or otherwise when you know what you are doing
|
||||||
|
/// Probably mostly useful for Components
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TcpServerConnector(Arc<String>);
|
||||||
|
|
||||||
|
impl TcpServerConnector {
|
||||||
|
/// Create a new connector with the given address
|
||||||
|
pub fn new(addr: String) -> Self {
|
||||||
|
Self(addr.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerConnectorError for Error {}
|
||||||
|
|
||||||
|
impl ServerConnector for TcpServerConnector {
|
||||||
|
type Stream = TcpStream;
|
||||||
|
type Error = Error;
|
||||||
|
async fn connect(
|
||||||
|
&self,
|
||||||
|
jid: &xmpp_parsers::Jid,
|
||||||
|
ns: &str,
|
||||||
|
) -> Result<XMPPStream<Self::Stream>, Self::Error> {
|
||||||
|
let stream = TcpStream::connect(&*self.0)
|
||||||
|
.await
|
||||||
|
.map_err(|e| crate::Error::Io(e))?;
|
||||||
|
Ok(XMPPStream::start(stream, jid.clone(), ns.to_owned()).await?)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue