From 3e1bb53c1b8ec0d17ed3b494fc920374892faf3d Mon Sep 17 00:00:00 2001 From: Nikita Vilunov Date: Tue, 21 Mar 2023 01:16:02 +0100 Subject: [PATCH] feat(xmpp): respond to unknown IQs with errors --- src/projections/xmpp/mod.rs | 15 +++++++++++++++ src/projections/xmpp/proto.rs | 13 +++++++++++-- src/protos/xmpp/client.rs | 2 +- src/util/xml.rs | 8 ++++---- src/util/xml/ignore.rs | 2 +- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/projections/xmpp/mod.rs b/src/projections/xmpp/mod.rs index 846d249..3aefb68 100644 --- a/src/projections/xmpp/mod.rs +++ b/src/projections/xmpp/mod.rs @@ -333,6 +333,21 @@ async fn socket_final( } xml_writer.get_mut().flush().await?; } + proto::IqClientBody::Unknown(_) => { + let mut events = vec![]; + let req = Iq { + from: None, + id: iq.id, + to: None, + r#type: xmpp::client::IqType::Error, + body: (), + }; + req.serialize(&mut events); + for i in events { + xml_writer.write_event_async(i).await?; + } + xml_writer.get_mut().flush().await?; + }, }, proto::ClientPacket::Message(_) => todo!(), proto::ClientPacket::Presence(p) => { diff --git a/src/projections/xmpp/proto.rs b/src/projections/xmpp/proto.rs index 2337868..008c77d 100644 --- a/src/projections/xmpp/proto.rs +++ b/src/projections/xmpp/proto.rs @@ -15,6 +15,7 @@ pub enum IqClientBody { Bind(BindRequest), Session(Session), Roster(RosterQuery), + Unknown(Ignore), } #[derive(From)] @@ -26,6 +27,7 @@ enum IqClientBodyParserInner { Bind(::P), SessionV(::P), RosterV(::P), + UnknownV(::P), } impl FromXml for IqClientBody { @@ -58,12 +60,16 @@ impl Parser for IqClientBodyParser { match_parser!(IqClientBodyParser, name, namespace, event; BindRequest, Session, - RosterQuery + RosterQuery, + { + IqClientBodyParser(Ignore::parse().into()).consume(namespace, event) + } ) } Bind(p) => delegate_parsing!(p, IqClientBodyParserInner, namespace, event), SessionV(p) => delegate_parsing!(p, IqClientBodyParserInner, namespace, event), RosterV(p) => delegate_parsing!(p, IqClientBodyParserInner, namespace, event), + UnknownV(p) => delegate_parsing!(p, IqClientBodyParserInner, namespace, event), } } } @@ -112,7 +118,10 @@ impl Parser for ClientPacketParser { match_parser!(ClientPacketParser, name, namespace, event; Iq::, Presence::, - Message + Message, + { + Continuation::Final(Err(ffail!("Unexpected XML event of name {:?} in namespace {:?}", name, namespace))) + } ) } IqV(p) => delegate_parsing!(p, ClientPacketParserInner, namespace, event), diff --git a/src/protos/xmpp/client.rs b/src/protos/xmpp/client.rs index 868fc78..6834947 100644 --- a/src/protos/xmpp/client.rs +++ b/src/protos/xmpp/client.rs @@ -97,7 +97,7 @@ impl Parser for MessageParser { } else if bytes.name().0 == b"body" { Continuation::Continue(InBody(state).into()) } else { - Continuation::Final(Err(ffail!("Unexpected XML tag"))) + Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))) } } Event::End(_) => { diff --git a/src/util/xml.rs b/src/util/xml.rs index 98f48a3..1c52549 100644 --- a/src/util/xml.rs +++ b/src/util/xml.rs @@ -59,18 +59,18 @@ macro_rules! delegate_parsing { } macro_rules! match_parser { - ($outer: ident, $name: expr, $ns: expr, $event: expr; $subtype: ty) => { + ($outer: ident, $name: expr, $ns: expr, $event: expr; $subtype: ty, $fin: block) => { if $name.0 == <$subtype as FromXmlTag>::NAME.as_bytes() && $ns == ResolveResult::Bound(Namespace(<$subtype as FromXmlTag>::NS.as_bytes())) { $outer(<$subtype as FromXml>::parse().into()).consume($ns, $event) } else { - Continuation::Final(Err(ffail!("Unexpected XML event of name {:?} in namespace {:?}", $name, $ns))) + $fin } }; - ($outer: ident, $name: expr, $ns: expr, $event: expr; $subtype: ty, $($rest: ty),+) => { + ($outer: ident, $name: expr, $ns: expr, $event: expr; $subtype: ty, $($rest: ty),+, $fin: block) => { if $name.0 == <$subtype as FromXmlTag>::NAME.as_bytes() && $ns == ResolveResult::Bound(Namespace(<$subtype as FromXmlTag>::NS.as_bytes())) { $outer(<$subtype as FromXml>::parse().into()).consume($ns, $event) } else { - match_parser!($outer, $name, $ns, $event; $($rest),*) + match_parser!($outer, $name, $ns, $event; $($rest),*, $fin) } }; } diff --git a/src/util/xml/ignore.rs b/src/util/xml/ignore.rs index 342e51e..4fe39e5 100644 --- a/src/util/xml/ignore.rs +++ b/src/util/xml/ignore.rs @@ -43,7 +43,7 @@ impl Parser for IgnoreParser { ) } } - _ => Continuation::Final(Ok(Ignore)), + _ => Continuation::Continue(IgnoreParserInner::InTag { name, depth }.into()), }, } }