Uploaded image for project: 'ejabberd development'
  1. ejabberd development
  2. EJAB-1382

Unable to use Stream Compression (XEP-0138) after SASL authentication

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: ejabberd 2.1.2
    • Fix Version/s: ejabberd 16.02
    • Component/s: XEP Support
    • Environment:
      Ubuntu 10.04.1 LTS (lucid), Ubuntu Ejabberd package 2.1.2-2, Erlang R13B03

      Description

      Problem

      After SASL authentication the server does not allow Stream Compression (XEP-0138) [1].

      Example 1. Ejabberd works correctly in this order

      1. TLS
      2. Stream compression
      3. SASL
      4. Resource binding

      Clients that use this order

      • Psi 0.14

      Example 2. (XEP-0170) [2] Ejabberd not accepting compression after SASL

      1. TLS
      2. SASL
      3. Stream compression (Feature is not listed by stream after SASL. Sending a compress will be ignored (ignoring is intended)
      4. Resource binding

      Although XEP-0170 [2] is just a best practice XEP, certain libraries (e.g. Smack) follow this practice.

      Clients that use this order

      • Smack

      How to replicate

      ejabberd_compression_test.py (https://gist.github.com/wpK/17de0b9a2c03b517afea)

      Example using ejabberd_compression_test.py (see above)

      Connecting to XMPP server jabber.ru on port 5222...
      Successfully connected to server.
      [S] <stream:stream to='jabber.ru' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
      [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='2572591128' from='jabber.ru' version='1.0' xml:lang='ru'>
      [R] <stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='rvAR01fKsc40hT0hOLGDuG25y9o='/><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
      [S] <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
      [R] <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
      [S] <stream:stream to='jabber.ru' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
      [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1990987535' from='jabber.ru' version='1.0' xml:lang='ru'>
      [R] <stream:features><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='rvAR01fKsc40hT0hOLGDuG25y9o='/><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
      [S] <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result='true'>REMOVED-AUTH-VALUE</auth>
      [R] <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
      [S] <stream:stream to='jabber.ru' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
      [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='3339712044' from='jabber.ru' version='1.0' xml:lang='ru'>
      [R] <stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='rvAR01fKsc40hT0hOLGDuG25y9o='/><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
      [S] <compress xmlns='http://jabber.org/protocol/compress'><method>zlib</method></compress>
      

      References

      1. http://xmpp.org/extensions/xep-0138.html
      2. http://xmpp.org/extensions/xep-0170.html

        Activity

        Hide
        badlop Badlop added a comment -

        Can you provide a bash script, or some other method to easily reproduce the problem?

        Show
        badlop Badlop added a comment - Can you provide a bash script, or some other method to easily reproduce the problem?
        Hide
        william William Key added a comment -

        Updated description with a script to reproduce the problem.

        Show
        william William Key added a comment - Updated description with a script to reproduce the problem.
        Hide
        neustradamus Neustradamus added a comment -

        Any news on it?

        Show
        neustradamus Neustradamus added a comment - Any news on it?
        Hide
        alexey Alexey Shchepin added a comment -

        Here is a patch enabling compression after auth, but I don't have a client to test it. Please someone test it and comment if it works or not.

        Show
        alexey Alexey Shchepin added a comment - Here is a patch enabling compression after auth, but I don't have a client to test it. Please someone test it and comment if it works or not.
        Hide
        cromain@process-one.net Christophe Romain (Inactive) added a comment - - edited

        Alexey Shchepin i tested the python script provided on this ticket on HEAD of master compiled with --enable-zlib, with and without your patch.

        without the patch:

        Connecting to XMPP server localhost on port 5222...
        Successfully connected to server.
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='2105536472' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features>
        [S] <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
        [R] <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1789332724' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features>
        [S] <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result='true'>AHRlc3QxQGxvY2FsaG9zdAB0ZXN0MQ==</auth>
        [R] <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='3907597178' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/></stream:features>
        [S] <compress xmlns='http://jabber.org/protocol/compress'><method>zlib</method></compress>
        .... stuck for a while ....
        [R] 
        [S] <iq type='set' id='bind'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>
        [R] 
        [S] </stream:stream>
        Unable to connect to chat server. Reason: [Errno 32] Broken pipe
        

        with your patch i get instant response:

        Connecting to XMPP server localhost on port 5222...
        Successfully connected to server.
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='3249693923' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features>
        [S] <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
        [R] <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1891399042' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features>
        [S] <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result='true'>AHRlc3QxQGxvY2FsaG9zdAB0ZXN0MQ==</auth>
        [R] <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
        [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
        [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='2790951111' from='localhost' version='1.0' xml:lang='en'>
        [R] <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression></stream:features>
        [S] <compress xmlns='http://jabber.org/protocol/compress'><method>zlib</method></compress>
        [R] <compressed xmlns='http://jabber.org/protocol/compress'/>
        [S] <iq type='set' id='bind'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>
        [R] 
        [S] </stream:stream>
        [R] 
        

        it seems the patch fix the problem. but script does not send anything after to ensure stream is working correctly and is effectively compressed as expected.
        it would requires deeper testing before integration.

        Show
        cromain@process-one.net Christophe Romain (Inactive) added a comment - - edited Alexey Shchepin i tested the python script provided on this ticket on HEAD of master compiled with --enable-zlib, with and without your patch. without the patch: Connecting to XMPP server localhost on port 5222... Successfully connected to server. [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='2105536472' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features> [S] <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> [R] <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='1789332724' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features> [S] <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result=' true '>AHRlc3QxQGxvY2FsaG9zdAB0ZXN0MQ==</auth> [R] <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='3907597178' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/></stream:features> [S] <compress xmlns='http: //jabber.org/protocol/compress'><method>zlib</method></compress> .... stuck for a while .... [R] [S] <iq type='set' id='bind'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq> [R] [S] </stream:stream> Unable to connect to chat server. Reason: [Errno 32] Broken pipe with your patch i get instant response: Connecting to XMPP server localhost on port 5222... Successfully connected to server. [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='3249693923' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features> [S] <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> [R] <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='1891399042' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism></mechanisms></stream:features> [S] <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result=' true '>AHRlc3QxQGxvY2FsaG9zdAB0ZXN0MQ==</auth> [R] <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> [S] <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' version='1.0'> [R] <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http: //etherx.jabber.org/streams' id='2790951111' from='localhost' version='1.0' xml:lang='en'> [R] <stream:features><c xmlns='http: //jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='ZCBMIiZf21RpW10Ddr7ad1+va9g='/><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression></stream:features> [S] <compress xmlns='http: //jabber.org/protocol/compress'><method>zlib</method></compress> [R] <compressed xmlns='http: //jabber.org/protocol/compress'/> [S] <iq type='set' id='bind'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq> [R] [S] </stream:stream> [R] it seems the patch fix the problem. but script does not send anything after to ensure stream is working correctly and is effectively compressed as expected. it would requires deeper testing before integration.
        Hide
        cromain@process-one.net Christophe Romain (Inactive) added a comment - - edited

        can someone interested by this feature test this patch on real condition with supported client ?

        Show
        cromain@process-one.net Christophe Romain (Inactive) added a comment - - edited can someone interested by this feature test this patch on real condition with supported client ?
        Hide
        holger Holger Weiß added a comment -

        We tested this with Smack now, and it's fixed in Git.

        Show
        holger Holger Weiß added a comment - We tested this with Smack now, and it's fixed in Git .

          People

          • Votes:
            5 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development