xmppo / xmpp-php

PHP client library for XMPP (Jabber) protocol
https://github.com/xmppo/xmpp-php
MIT License
45 stars 23 forks source link

Resource binding before authentication #4

Closed andriusvo closed 5 years ago

andriusvo commented 5 years ago

Hey, found your library and in love with the simplicity, but there is actually one issue. Trying to setup library on Symfony frramework, successfully did it, but then I'm trying to send message got this error:

Cannot bind resource before authentication

After setting TLS to TRUE, after setting resource response is "invalid-namespace" and message is not delivered. Please fix ASAP!!

` protected static $host = 616.pub'; protected static $port = 5222; protected static $username = 'randomas1'; protected static $password = 'randomas1';

/**
 * @Route("/", name="homepage")
 */
public function indexAction(Request $request)
{
    $options = new Options();

    $options
        ->setHost(self::$host)
        ->setPort(self::$port)
        ->setUsername(self::$username)
        ->setPassword(self::$password);

    $client = new XmppClient($options);
    $client->connect();
    $client->iq->getRoster();

    $client->message->send('Hello world', 'randomas1@618.pub');

    return new Response($client->getResponse());`
Norgul commented 5 years ago

Hello, glad you like it :)

If you check out the server response you will notice this section:

<stream:features>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
        <required/>
    </starttls>
</stream:features>

It is showing that TLS is required before authentication can take place. I have just implemented that part in the last version (get the v2.1.1.) so you can add to your options setUseTls(true). This will trigger TLS first and then use one of the auth methods afterwards.

I do see some error after saying:

<stream:error>
    <invalid-namespace xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>

I will check that out.

andriusvo commented 5 years ago

Yes, I added TLS to my code, but then invalid-namespace appears! It would be great if you fix it asap, because need to continue my project.

Norgul commented 5 years ago

I will need to re-do the SASL negotiation process as it obviously has some conditioning depending on what the server responds with. I did make some progress, but I will need to do a bit of dive in RFC's to see the details. Give me a bit more time and I'll resolve it

Norgul commented 5 years ago

If you need it for testing though, for the first hand you can go to XmppClient.php and change the connect method to following:

public function connect()
{
    $this->openStream();

    if ($this->options->usingTls()) {
        $this->startTls();
    }

    $this->authenticate();

    echo "\nPost auth\n";
    $response = $this->getResponse();
    $this->prettyPrint($response);

    $this->openStream();

    echo "\nAnother opening\n";
    $response = $this->getResponse();
    $this->prettyPrint($response);

    $this->iq->setResource($this->options->getResource());

    echo "\nPost resource\n";
    $response = $this->getResponse();
    $this->prettyPrint($response);

    $this->sendInitialPresenceStanza();
}

Unfortunately if you remove the part where you are fetching the response, it doesn't work, and I suppose that it is all due to the fact that you actually need to wait for answer from the server (which I am currently not doing). I will try to resolve it all and see where I end up.

andriusvo commented 5 years ago

Ok, will wait for your solution.

Norgul commented 5 years ago

Hello @SSMellow could you try out the new version now? I am implementing fix for auth renegotiation, I will add some more logging to it, but it should be functional enough for your use now.

Try it out and tell me if it needs something else

andriusvo commented 5 years ago

It seems like you aren’t testing it or I just don’t know hot to use it. Messages are working fine, but Roster isn’t. How I should get a contact list? Fron $client->iq->getRoster() or from $client->getResponse() because both are not responding contacts

Norgul commented 5 years ago

XMPP communication consists of request and response. With $client->iq->getRoster() you are issuing a request to the server to return roster (contact list). Once the request is sent, you need to read the response from the server with $client->getResponse().

I've tried it, and I am getting the following (xxx's are "censored" names):

<iq id='5cc6a824b4442' type='result' to='xxx@616.pub/norgul_machine_1556523041'>
    <query xmlns='jabber:iq:roster' ver='6'>
        <item subscription='none' name='xxx' ask='subscribe' jid='xxx@618.pub'/>
        <item subscription='none' name='xxx' ask='subscribe' jid='xxx@616.pub'/>
        <item subscription='none' name='xxx' ask='subscribe' jid='xxx@618.pub'/>
    </query>
</iq>

From this you should parse the XML from the response to fetch the data you need.

You are right though, this might not be as intuitive as someone might want it to be (that's why I need users like you to point me to the right direction) because GET roster indicates you are getting something, where in reality you are sending data to the server. I have already started with parser implementation, I will think about the best way to do it so it can be more intuitive.

andriusvo commented 5 years ago

`$options = new Options();

    $options
        ->setHost(self::$host)
        ->setPort(self::$port)
        ->setUsername(self::$username)
        ->setPassword(self::$password)
        ->setUseTls(true);

    $client = new XmppClient($options);
    $client->connect();
    $client->iq->getRoster();
    $resp = $client->getResponse();
    $client->prettyPrint($resp);

`

randomas1@616.pub/norgul_machine_15565558520Server-to-server connection failed: Connecting failed: No route to hostServer-to-server connection failed: Connecting failed: No route to host

You can try with my data (in the first post), no response :/

Norgul commented 5 years ago

Okay so, I have made the fix, you should be able to see the response now connecting fine.

Also implemented logger. When you run the program, 3 files should be created:

request.xml -> containing XML's sent to the server response.xml -> containing XML's received from the server xmpp.log -> will contain all other logs (currently empty)

Files get re-written with each new session created. Solution is a bit dirty so I will clean it up when I get the chance (sorry, with the daytime job and side projects it's hard to keep the speed up), but working on it.

Also parser is soon to be functional, so you won't have to do that part manually.

P.S. if you're using PHPStorm, when in *.xml file you can do cmd+alt+L on Mac for auto format (don't remember the Win shortcut) and you will see the response formatted nicely.