pgstath / Sharp.Xmpp

Sharp.Xmpp is looking for a maintainer! Unfortunatelly I do not have currently the time needed to maintain the library. Luckily a small but vibrant community has evolved around Sharp.Xmpp. If you would like to be the project's maintainer please sent an email to pgstath@gmail.com. This should include issues, tickets and commits that you have done for Sharp.Xmpp or other similar project. Sharp.Xmpp is a multiplatform, Windows and Android, .NET XMPP client assembly.Sharp.Xmpp supports IM functionality & a variety of XMPP extensions, is simple and is extensively tested against Android Xamarin. It is a fork of the currently frozen excellent S22.Xmpp project. Sharp.Xmpp will be at the FOSSDEM 2016 Real time DevRoom!
Other
84 stars 51 forks source link

"Root element is missing" on auth StreamParser #35

Closed i8beef closed 2 years ago

i8beef commented 7 years ago

Ok, this is a little different and if I'm too far out of spec for this library that's fine. Hoping someone might be able to point me to what I'm doing wrong.

I'm playing with communicating with a Logitech Harmony Hub. It runs an XMPP server on 5222 on the device. There is some preamble auth ticket negotiation done before the actual login attempt through XMPP, which I have working ok, but when I attempt to actually connect, I'm getting an XmppException, with an inner exception coming from the StreamParser during the login attempt, from the XmlStreamReader of "Root element is missing.".

Login type should be XMPP SASL PLAIN.

Basics of what I'm attempting to recreate are here: https://github.com/jterrace/pyharmony/blob/master/PROTOCOL.md

using (var authClient = new XmppCore(ip, "guest@x.com", "guest", 5222, false))
{
    authClient.Connect();
}

at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.ParseDocumentContent() at System.Xml.XmlTextReaderImpl.Read() at Sharp.Xmpp.Core.StreamParser.ReadRootElement() at Sharp.Xmpp.Core.StreamParser..ctor(Stream stream, Boolean leaveOpen) at Sharp.Xmpp.Core.XmppCore.InitiateStream(String hostname) at Sharp.Xmpp.Core.XmppCore.Authenticate(IEnumerable`1 mechanisms, String username, String password, String hostname) at Sharp.Xmpp.Core.XmppCore.SetupConnection(String resource) at Sharp.Xmpp.Core.XmppCore.Connect(String resource)

jpenny1993 commented 7 years ago

Granted that you don't want a roster and want to access IqRequest functionality your example looks fine.

The XmlReader in ReadRootElement() doesn't seem to be able to read whats in the stream. Maybe try putting a breakpoint around there and have a look at whats in the stream object at that point.

i8beef commented 7 years ago

So following through the logic here, it looks like the code here is:

  1. Opening a new STREAM (stream:stream)
  2. Establishes an auth method from the return features from the server
  3. Sends an authenticate message ()
  4. Validates the signature, if any
  5. Initiates a new stream (XmppCore line 1018) WITHOUT closing the first stream.

That doesn't seem right to me... When I do that in a console app, it immediately kicks me out.

jpenny1993 commented 7 years ago

Yeah, It's not right. I knew the library dropped the initial connection when the logon method is called. This is because it was easier to reconnect with credentials then to authentication handshake separately. I didn't realise it would do it if you've given the ctor it credentials. I personally threw a trycatch around the authenticate method so I could do my stuff. I'll take a look at it when it's not 11pm, also if I make a pull request it might not make it in straight away.

It could be worth you forking the project and helping fix it if you're definitely sticking with this library. Although I'd suggest checking out ubiety/xmpp first if you haven't yet.

i8beef commented 2 years ago

Cleaning my old tickets, I ended up implementing my own socket based approach to parsing the XMPP stream outside this library.