2020-12-26 19:11:23 +00:00
|
|
|
use sasl::client::MechanismError as SaslMechanismError;
|
2018-09-06 15:46:06 +00:00
|
|
|
use std::borrow::Cow;
|
2018-12-18 18:04:31 +00:00
|
|
|
use std::error::Error as StdError;
|
2018-09-06 15:46:06 +00:00
|
|
|
use std::fmt;
|
2018-12-18 18:04:31 +00:00
|
|
|
use std::io::Error as IoError;
|
2023-05-30 15:37:52 +00:00
|
|
|
use std::str::Utf8Error;
|
2018-09-06 16:20:05 +00:00
|
|
|
|
2018-09-06 15:46:06 +00:00
|
|
|
use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition;
|
2020-03-05 00:25:24 +00:00
|
|
|
use xmpp_parsers::{Error as ParsersError, JidParseError};
|
2018-09-06 15:46:06 +00:00
|
|
|
|
2023-12-31 03:08:37 +00:00
|
|
|
use crate::connect::ServerConnectorError;
|
|
|
|
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Top-level error type
|
2019-09-05 20:25:28 +00:00
|
|
|
#[derive(Debug)]
|
2018-09-06 15:46:06 +00:00
|
|
|
pub enum Error {
|
2018-09-07 23:42:23 +00:00
|
|
|
/// I/O error
|
2018-09-06 15:46:06 +00:00
|
|
|
Io(IoError),
|
2020-03-05 00:25:24 +00:00
|
|
|
/// Error parsing Jabber-Id
|
|
|
|
JidParse(JidParseError),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Protocol-level error
|
2018-09-06 15:46:06 +00:00
|
|
|
Protocol(ProtocolError),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Authentication error
|
2018-09-06 15:46:06 +00:00
|
|
|
Auth(AuthError),
|
2018-12-20 19:39:01 +00:00
|
|
|
/// Connection closed
|
|
|
|
Disconnected,
|
2024-05-13 20:54:26 +00:00
|
|
|
/// Should never happen
|
2018-09-06 15:46:06 +00:00
|
|
|
InvalidState,
|
2023-05-30 15:37:52 +00:00
|
|
|
/// Fmt error
|
|
|
|
Fmt(fmt::Error),
|
|
|
|
/// Utf8 error
|
|
|
|
Utf8(Utf8Error),
|
2023-12-31 03:08:37 +00:00
|
|
|
/// Error resolving DNS and/or establishing a connection, returned by a ServerConnector impl
|
|
|
|
Connection(Box<dyn ServerConnectorError>),
|
2018-09-06 15:46:06 +00:00
|
|
|
}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
Error::Io(e) => write!(fmt, "IO error: {}", e),
|
|
|
|
Error::Connection(e) => write!(fmt, "connection error: {}", e),
|
2020-03-05 00:25:24 +00:00
|
|
|
Error::JidParse(e) => write!(fmt, "jid parse error: {}", e),
|
2019-09-05 20:25:28 +00:00
|
|
|
Error::Protocol(e) => write!(fmt, "protocol error: {}", e),
|
|
|
|
Error::Auth(e) => write!(fmt, "authentication error: {}", e),
|
|
|
|
Error::Disconnected => write!(fmt, "disconnected"),
|
|
|
|
Error::InvalidState => write!(fmt, "invalid state"),
|
2023-05-30 15:37:52 +00:00
|
|
|
Error::Fmt(e) => write!(fmt, "Fmt error: {}", e),
|
|
|
|
Error::Utf8(e) => write!(fmt, "Utf8 error: {}", e),
|
2019-09-05 20:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-23 11:09:26 +00:00
|
|
|
impl StdError for Error {}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl From<IoError> for Error {
|
|
|
|
fn from(e: IoError) -> Self {
|
|
|
|
Error::Io(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-31 03:08:37 +00:00
|
|
|
impl<T: ServerConnectorError + 'static> From<T> for Error {
|
|
|
|
fn from(e: T) -> Self {
|
|
|
|
Error::Connection(Box::new(e))
|
2019-09-05 20:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-05 00:25:24 +00:00
|
|
|
impl From<JidParseError> for Error {
|
|
|
|
fn from(e: JidParseError) -> Self {
|
|
|
|
Error::JidParse(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl From<ProtocolError> for Error {
|
|
|
|
fn from(e: ProtocolError) -> Self {
|
|
|
|
Error::Protocol(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<AuthError> for Error {
|
|
|
|
fn from(e: AuthError) -> Self {
|
|
|
|
Error::Auth(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-30 15:37:52 +00:00
|
|
|
impl From<fmt::Error> for Error {
|
|
|
|
fn from(e: fmt::Error) -> Self {
|
|
|
|
Error::Fmt(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Utf8Error> for Error {
|
|
|
|
fn from(e: Utf8Error) -> Self {
|
|
|
|
Error::Utf8(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-06 15:46:06 +00:00
|
|
|
/// XML parse error wrapper type
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ParseError(pub Cow<'static, str>);
|
|
|
|
|
|
|
|
impl StdError for ParseError {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
self.0.as_ref()
|
|
|
|
}
|
2019-06-12 14:29:55 +00:00
|
|
|
fn cause(&self) -> Option<&dyn StdError> {
|
2018-09-06 15:46:06 +00:00
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for ParseError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{}", self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-07 23:42:23 +00:00
|
|
|
/// XMPP protocol-level error
|
2019-09-05 20:25:28 +00:00
|
|
|
#[derive(Debug)]
|
2018-09-06 15:46:06 +00:00
|
|
|
pub enum ProtocolError {
|
2018-09-07 23:42:23 +00:00
|
|
|
/// XML parser error
|
2022-03-22 22:29:25 +00:00
|
|
|
Parser(minidom::Error),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Error with expected stanza schema
|
2018-09-06 15:46:06 +00:00
|
|
|
Parsers(ParsersError),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// No TLS available
|
2018-09-06 15:46:06 +00:00
|
|
|
NoTls,
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Invalid response to resource binding
|
2018-09-06 15:46:06 +00:00
|
|
|
InvalidBindResponse,
|
2018-09-07 23:42:23 +00:00
|
|
|
/// No xmlns attribute in <stream:stream>
|
2018-09-06 15:46:06 +00:00
|
|
|
NoStreamNamespace,
|
2018-09-07 23:42:23 +00:00
|
|
|
/// No id attribute in <stream:stream>
|
2018-09-06 15:46:06 +00:00
|
|
|
NoStreamId,
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Encountered an unexpected XML token
|
2018-09-06 15:46:06 +00:00
|
|
|
InvalidToken,
|
2019-01-26 20:07:15 +00:00
|
|
|
/// Unexpected <stream:stream> (shouldn't occur)
|
|
|
|
InvalidStreamStart,
|
2018-09-06 15:46:06 +00:00
|
|
|
}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl fmt::Display for ProtocolError {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
ProtocolError::Parser(e) => write!(fmt, "XML parser error: {}", e),
|
|
|
|
ProtocolError::Parsers(e) => write!(fmt, "error with expected stanza schema: {}", e),
|
|
|
|
ProtocolError::NoTls => write!(fmt, "no TLS available"),
|
2019-10-22 23:32:41 +00:00
|
|
|
ProtocolError::InvalidBindResponse => {
|
|
|
|
write!(fmt, "invalid response to resource binding")
|
|
|
|
}
|
|
|
|
ProtocolError::NoStreamNamespace => {
|
|
|
|
write!(fmt, "no xmlns attribute in <stream:stream>")
|
|
|
|
}
|
2019-09-05 20:25:28 +00:00
|
|
|
ProtocolError::NoStreamId => write!(fmt, "no id attribute in <stream:stream>"),
|
|
|
|
ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"),
|
|
|
|
ProtocolError::InvalidStreamStart => write!(fmt, "unexpected <stream:stream>"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-23 11:09:26 +00:00
|
|
|
impl StdError for ProtocolError {}
|
|
|
|
|
2022-03-22 22:29:25 +00:00
|
|
|
impl From<minidom::Error> for ProtocolError {
|
|
|
|
fn from(e: minidom::Error) -> Self {
|
2019-09-05 20:25:28 +00:00
|
|
|
ProtocolError::Parser(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-22 22:29:25 +00:00
|
|
|
impl From<minidom::Error> for Error {
|
|
|
|
fn from(e: minidom::Error) -> Self {
|
|
|
|
ProtocolError::Parser(e).into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl From<ParsersError> for ProtocolError {
|
|
|
|
fn from(e: ParsersError) -> Self {
|
|
|
|
ProtocolError::Parsers(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Authentication error
|
2019-09-05 20:25:28 +00:00
|
|
|
#[derive(Debug)]
|
2018-09-06 15:46:06 +00:00
|
|
|
pub enum AuthError {
|
2018-09-07 23:42:23 +00:00
|
|
|
/// No matching SASL mechanism available
|
2018-09-06 15:46:06 +00:00
|
|
|
NoMechanism,
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Local SASL implementation error
|
2020-12-26 19:11:23 +00:00
|
|
|
Sasl(SaslMechanismError),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Failure from server
|
2018-09-06 15:46:06 +00:00
|
|
|
Fail(SaslDefinedCondition),
|
2018-09-07 23:42:23 +00:00
|
|
|
/// Component authentication failure
|
2018-09-06 15:46:06 +00:00
|
|
|
ComponentFail,
|
|
|
|
}
|
|
|
|
|
2022-03-23 11:09:26 +00:00
|
|
|
impl StdError for AuthError {}
|
|
|
|
|
2019-09-05 20:25:28 +00:00
|
|
|
impl fmt::Display for AuthError {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
AuthError::NoMechanism => write!(fmt, "no matching SASL mechanism available"),
|
|
|
|
AuthError::Sasl(s) => write!(fmt, "local SASL implementation error: {}", s),
|
|
|
|
AuthError::Fail(c) => write!(fmt, "failure from the server: {:?}", c),
|
|
|
|
AuthError::ComponentFail => write!(fmt, "component authentication failure"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|