Bug 39057

Summary: Can't connect to Oracle Jabber server
Product: Telepathy Reporter: Guillaume Desmottes <guillaume.desmottes>
Component: gabbleAssignee: Telepathy bugs list <telepathy-bugs>
Status: RESOLVED MOVED QA Contact: Telepathy bugs list <telepathy-bugs>
Severity: normal    
Priority: medium CC: bugs, freedesktop, leon+freedesktop
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
URL: http://cgit.collabora.com/git/user/xclaesse/wocky.git/log/?h=fix-msn
Whiteboard:
i915 platform: i915 features:
Attachments: patch for 0.18.3
patch for 0.18.3

Description Guillaume Desmottes 2011-07-08 00:18:26 UTC
Original bug report: https://bugzilla.gnome.org/show_bug.cgi?id=654011

There are at least 2 issues preventing Gabble to interop with Oracle's Jabber Server.

A) Their SSL/TLS implementation is on crack as explained on https://bugzilla.gnome.org/show_bug.cgi?id=654011#c9
This can we be work arounded using env variable but it may be best to expose a connection param instead.

B) Once connected Gabble isn't happy and close the stream see https://bugzilla.gnome.org/attachment.cgi?id=191464
Comment 1 Philip Antoniades 2011-07-08 07:18:29 UTC
I'm the originator here - I'm using Fedora 15, but my coworkers and I have hit this on various releases of Ubuntu and SuSE as well.
Comment 2 Philip Antoniades 2011-07-25 08:37:44 UTC
Any guidance here? 

This affects a growing pool of users in the MySQL and Oracle Linux teams. 

thanks, 

Philip
Comment 3 Will Thompson 2011-09-26 07:03:09 UTC
(In reply to comment #0)
> B) Once connected Gabble isn't happy and close the stream see
> https://bugzilla.gnome.org/attachment.cgi?id=191464

Here's the problem. Gabble sends a disco query to the user's own bare JID:

(telepathy-gabble:24977): gabble-DEBUG: gabble_disco_request_with_timeout (disco.c:509): Creating disco request 0x8563940 for philip.antoniades@oracle.com
(telepathy-gabble:24977): wocky-DEBUG: _write_node_tree: Serializing tree:
* iq xmlns='jabber:client' type='get' to='philip.antoniades@oracle.com' id='65803733515'
    * query xmlns='http://jabber.org/protocol/disco#info'
(telepathy-gabble:24977): wocky-DEBUG: Writing xml: <iq type="get" to="philip.antoniades@oracle.com" id="65803733515"><query xmlns="http://jabber.org/protocol/disco#info"/></iq>

Some time later, the server replies:

(telepathy-gabble:24977): wocky-DEBUG: Parsing chunk: <iq id="65803733515" type="error" from="oracle.com" to="philip.antoniades@oracle.com/d1f5ca92"><query xmlns='http://jabber.org/protocol/disco#info' >
</query><error code="404" type="cancel"><item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
(telepathy-gabble:24977): wocky-DEBUG: _end_element_ns: Received stanza
* iq xmlns='jabber:client' id='65803733515' type='error' from='oracle.com' to='philip.antoniades@oracle.com/d1f5ca92'
    * query xmlns='http://jabber.org/protocol/disco#info'
        "
"
    * error code='404' type='cancel'
        * item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'

But the JID on the reply is wrong: we sent the disco query to philip.antoniades@oracle.com, but the server's reply is from='oracle.com'.

(telepathy-gabble:24977): wocky-DEBUG: check_spoofing: wocky-c2s-porter.c:839: 'oracle.com' (normal: 'oracle.com') attempts to spoof an IQ reply from 'philip.antoniades@oracle.com'
(telepathy-gabble:24977): wocky-DEBUG: check_spoofing: wocky-c2s-porter.c:841: Our full JID is 'philip.antoniades@oracle.com/d1f5ca92' and our bare JID is 'philip.antoniades@oracle.com'
(telepathy-gabble:24977): gabble-DEBUG: gabble_normalize_contact (util.c:557): JID oracle.com is invalid or has no node part
(telepathy-gabble:24977): gabble-DEBUG: got_jingle_info_stanza (jingle-factory.c:274): ignoring jingleinfo from 'oracle.com', not ourself nor the server
(telepathy-gabble:24977): wocky-DEBUG: handle_stanza: wocky-c2s-porter.c:983: Stanza not handled

And then some time later, the disco query times out:

(telepathy-gabble:24977): gabble-DEBUG: bare_jid_disco_cb (connection.c:1694): Got disco error on bare jid: Request for info on philip.antoniades@oracle.com timed out

While I don't think it's actually allowed to behave this way, we could make that function tolerate this in the same way that, if one sends an IQ to one's own full JID, or with no to='', the server can reply with no from='', with from='bare jid' or with from='full jid'.
Comment 4 Jared Greenwald 2011-09-26 17:58:25 UTC
I have filed an Oracle internal bug against the beehive server for this.
Comment 5 Xavier Claessens 2011-10-26 03:12:31 UTC
xmpp.messenger.live.com has this same issue, here is a fix:

http://cgit.collabora.com/git/user/xclaesse/wocky.git/commit/?h=fix-msn&id=cfa889313dc25493dd10373f0038e51d9823ab84
Comment 6 Will Thompson 2011-10-28 10:48:10 UTC
(In reply to comment #5)
> xmpp.messenger.live.com has this same issue, here is a fix:
> 
> http://cgit.collabora.com/git/user/xclaesse/wocky.git/commit/?h=fix-msn&id=cfa889313dc25493dd10373f0038e51d9823ab84

This change looks about right, but I would like there to be a test for it in Wocky. You can add a single line to handler_from_anyone() in tests/wocky-porter-test.c to test it.
Comment 7 Xavier Claessens 2011-11-02 05:37:17 UTC
Branch updated now with unit test.

The fix was actually making another unit test fail, because stanza_is_from_server() is also used in handle_stanza() where we do not want to match domain as coming from server, according to this unit test:

  /* Slightly counterintuitively, a stanza from our server's domain should not
   * be matched by got_stanza_from_server().
   */
  send_query_from (test, "capulet.lit", "anyone");
Comment 8 Xavier Claessens 2011-11-04 03:24:31 UTC
(In reply to comment #7)
>   /* Slightly counterintuitively, a stanza from our server's domain should not
>    * be matched by got_stanza_from_server().
>    */
>   send_query_from (test, "capulet.lit", "anyone");

Wjt mentioned that test is actually what we want to change for the oracle case. I'm not really sure tbh, at least it's not what makes MSN fail. If I understand correctly the oracle logs, what happens is that we receive a *reply* for a stanza we sent to *server* and in that case server replies with from="domain". If I understand the unit test above, it gets a stanza which is not a reply to a message destined to server, so it is not exactly the same thing.

Or maybe both cases should be changed?
Comment 9 Will Thompson 2011-11-07 03:02:35 UTC
(In reply to comment #8)
> (In reply to comment #7)
> >   /* Slightly counterintuitively, a stanza from our server's domain should not
> >    * be matched by got_stanza_from_server().
> >    */
> >   send_query_from (test, "capulet.lit", "anyone");
> 
> Wjt mentioned that test is actually what we want to change for the oracle case.
> I'm not really sure tbh, at least it's not what makes MSN fail. If I understand
> correctly the oracle logs, what happens is that we receive a *reply* for a
> stanza we sent to *server* and in that case server replies with from="domain".
> If I understand the unit test above, it gets a stanza which is not a reply to a
> message destined to server, so it is not exactly the same thing.
> 
> Or maybe both cases should be changed?

I wouldn't be opposed to changing both cases.

• _from_server matching the domain of the user's own JID, as well as node@domain and node@domain/resource (and unspecified from) would also be useful on bug 41417. It would remove the counterintuitivity my comment you quote refers to.
• allowing replies to IQs we sent to our own JID to come back from our own domain also seems reasonable, and would fix an actual bug. (Just as long as we don't allow replies for IQs we send to any other JIDs besides our own to come back from the wrong place.)
Comment 10 Xavier Claessens 2011-11-08 01:02:30 UTC
Ok, did that and pushed.
Comment 11 Miguel Tadeu 2013-08-12 15:24:27 UTC
This problem is not solved. I'm reopening it.

The SSL problem seems solved but the bareid disco problem isn't.
Comment 12 Simon McVittie 2013-09-17 16:04:30 UTC
17-09-2013 16:46:54.259099 - [wocky] check_spoofing: wocky-c2s-porter.c:874: 'oracle.com' (normal: 'oracle.com') attempts to spoof an IQ reply from 'firstname.lastname@oracle.com'
17-09-2013 16:46:54.259140 - [wocky] check_spoofing: wocky-c2s-porter.c:876: Our full JID is 'firstname.lastname@oracle.com/kde-telepathy-629632' and our bare JID is 'firstname.lastname@oracle.com'

This is similar to Bug #68829 but not the same. This:

   /* if we sent an IQ to our full or bare JID, allow our server to omit 'to'
    * in the reply (Prosody 0.6.1 does this with the resulting error if we
    * send disco#info to our own bare JID), or to use our full JID. */

needs to be made even less strict: the server is replying from its own server name, so it'll need to allow that *as well*.

Please report this as a server bug, too: replies should match their requests.
Comment 13 Malte Starostik 2013-09-26 14:23:41 UTC
This one seems to be the same basic issue?
I Can't connect to our internal Cisco Unified Presence server:

26.09.2013 16:14:26.903222 - [gabble/connection] create_invisible_privacy_list_async (conn-presence.c:736): Creating 'invisible'
26.09.2013 16:14:26.903295 - [wocky] _write_node_tree: Serializing tree:
* iq xmlns='jabber:client' type='set' id='278600903271'
    * query xmlns='jabber:iq:privacy'
        * list name='invisible'
            * item action='deny' order='1'
                * presence-out
26.09.2013 16:14:26.947413 - [wocky] _end_element_ns: Received stanza
* iq xmlns='jabber:client' from='privacy-cm.uc-cup2' id='278600903271' to='user@domain/resource' type='error'
    * error type='cancel'
        * item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
26.09.2013 16:14:26.947540 - [wocky] check_spoofing: wocky-c2s-porter.c:885: 'privacy-cm.uc-cup2' (normal: 'privacy-cm.uc-cup2') attempts to spoof an IQ reply from '(null)'
26.09.2013 16:14:26.947576 - [wocky] check_spoofing: wocky-c2s-porter.c:887: Our full JID is 'user@domain/resource' and our bare JID is 'user@domain'
26.09.2013 16:14:26.947612 - [wocky] handle_stanza: wocky-c2s-porter.c:1034: Stanza not handled

All instances of "user", "domain", and "resource" were actually the correct values for my account.
If I bypass the spoofing check, the connection succeeds.
"uc-cup2" is the actual CM server's name, no idea why it isn't an FQDN or if that matters at all. No idea what "privacy-cm.uc-cup2" is, presumably some service implementing the invisibility?

Tested the same server and account with Kopete, Jitsi and Xabber and they all connect just fine.
Comment 14 Simon McVittie 2013-09-26 14:51:21 UTC
(In reply to comment #13)
> 26.09.2013 16:14:26.903295 - [wocky] _write_node_tree: Serializing tree:
> * iq xmlns='jabber:client' type='set' id='278600903271'
>     * query xmlns='jabber:iq:privacy'
>         * list name='invisible'
>             * item action='deny' order='1'
>                 * presence-out
> 26.09.2013 16:14:26.947413 - [wocky] _end_element_ns: Received stanza
> * iq xmlns='jabber:client' from='privacy-cm.uc-cup2' id='278600903271'
> to='user@domain/resource' type='error'
>     * error type='cancel'
>         * item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
> 26.09.2013 16:14:26.947540 - [wocky] check_spoofing: wocky-c2s-porter.c:885:
> 'privacy-cm.uc-cup2' (normal: 'privacy-cm.uc-cup2') attempts to spoof an IQ
> reply from '(null)'

Just to confirm, your domain is not in fact privacy-cm.uc-cup2?

The spoofing check is correct to reject this: this reply is indistinguishable from an unrelated XMPP user('s server) doing something malicious. We don't have any way to know that stanzas claiming to be from privacy-cm.uc-cup2 (whatever that is) are valid replies to a stanza that was (implicitly) sent to user@domain.

(If our own full JID is user@domain/resource, then omitting the 'to' on a stanza is meant to be exactly equivalent to setting to='user@domain' - we're asking our own "home" server to handle the stanza on our behalf.)
Comment 15 Malte Starostik 2013-09-27 14:01:41 UTC
(In reply to comment #14)
> Just to confirm, your domain is not in fact privacy-cm.uc-cup2?

No, that is not the domain.  However, uc-cup2 is the (unqualified) name of the server I'm connected to.  To be more precise _jabber-client._tcp.domain SRV-resolves to uc-cup1.domain and uc-cup2.domain.  Only "domain" is not literally "domain", but consistently refers our real domain name wherever I mentioned it.
 
> The spoofing check is correct to reject this: this reply is
> indistinguishable from an unrelated XMPP user('s server) doing something
> malicious. We don't have any way to know that stanzas claiming to be from
> privacy-cm.uc-cup2 (whatever that is) are valid replies to a stanza that was
> (implicitly) sent to user@domain.

So, uc-cup2 is the home server but the privacy-cm. prefix entered the stage just here.

> (If our own full JID is user@domain/resource, then omitting the 'to' on a
> stanza is meant to be exactly equivalent to setting to='user@domain' - we're
> asking our own "home" server to handle the stanza on our behalf.)

I can see how this is correct.  Still this apparently breaks logging in to Cisco's presence server.  Well, if that's against the spec, they should probably know better given this statement:

"Cisco Unified Presence supports standards-based XMPP to enable third-party XMPP client applications to integrate with Cisco Unified Presence for availability and instant messaging (IM) services. Third-party XMPP clients must comply with the XMPP standard as outlined in the Cisco Software Development Kit (SDK)."

http://www.cisco.com/en/US/docs/voice_ip_comm/cups/8_0/english/install_upgrade/deployment/guide/dgXMPPclient.html

But then there are certainly funnier things to do than convince them of this being a bug in their server - let alone actually geting a fixed version.  Therefore a workaround would be much appreciated - especially as other clients can do this.

If I parse that log correctly, this is only about creating an invisible list?  So maybe this error could at least gracefully lead to disabling this feature or the likes?
Comment 16 Simon McVittie 2013-09-27 14:40:40 UTC
(In reply to comment #15)
> So, uc-cup2 is the home server but the privacy-cm. prefix entered the stage
> just here.

uc-cup2 is not the home server; that would be "domain" (or possibly "uc-cup2.domain" if you interpret it that way). Gabble doesn't have any way to know that "uc-cup2" is under the same administrative control as example.com.

> Therefore a workaround would be much appreciated - especially as other
> clients can do this.

I want to help here, but I also don't want to enable denial of service attacks (or worse), which is what the spoofing check is intended to prevent.

In this case, if we added an "it's OK if the reply is spoofed" flag and used it for this query, what an attacker might be able to do is to tell users of other servers that they can't be invisible, when actually, they can. Not the worst thing in the world, but not really desirable.

> If I parse that log correctly, this is only about creating an invisible
> list?  So maybe this error could at least gracefully lead to disabling this
> feature or the likes?

We're waiting for the reply to "can I be invisible here?" before sending our initial presence, so that the initial presence can be invisible if desired. The reply "came from the wrong place" and was discarded, so we'll never proceed.

One possible workaround would be to put an arbitrary timeout on it: if we don't get a reply to this question reasonably promptly, carry on regardless. It'll take you longer to log in than it should, but you'll be able to log in.

A more elaborate workaround would be something like this: assume that the server will reply to simple stanzas like this in-order. Send the "can I be invisible?" query, then a different query. If we get a reply to the second query before we have had a (valid) reply to "can I be invisible?", assume that the answer is "no, you can't".
Comment 17 Simon McVittie 2013-09-27 14:43:17 UTC
Another possible workaround would be to have an "advanced option" for "try to get invisibility support", and as the workaround, you'd have to turn it off. That'd be somewhat useful for bandwidth-constrained users who happen to know that their server doesn't do invisibility, too.
Comment 18 Malte Starostik 2013-09-27 17:15:36 UTC
Either approach seems fine to me.  Don't think with my lack of knowledge about XMPP and wocky I can be of help wrt coding, but I'll gladly give any implementation a test ride with our server.

Just checked again if I could get the server to at least prepend the domain name to that JID, but the best I could get is privacy-cm.uc-cup2-pseudo-domain where "pseudo-domain" is the domain name with all dots turned to dashes.
Comment 19 Leonid Evdokimov 2015-08-14 08:57:42 UTC
Created attachment 117676 [details] [review]
patch for 0.18.3

I suggest following patch to be applied after improvements. Let me describe the patch.

1) `id` generation is improved: predictable nonce is replaced with secure random number
2) if stanza is sent to `our` server AND connection to `our` server is TLS-protected, then `id` can't be sniffed

IMHO, these two points and the fact that spoofing() is called after checking `id` match make dropping `from` checks for to-our-server stanzas secure enough.
I do not drop `from` check, but replace it with `privacy-cm.` prefix lookup to make it clear, that it's workaround for buggy server.

There is possible improvement in `id` generation – trivial N-bit random string may be replaced with ECB-encrypted nonce. nonce should be at least 64-bit in this case and encryption key should be changed once per session. That will make shift id reuse from `improbable` to `impossible`, but I'm not sure if additional complexity makes sense.

I also think that `from` check can be safely dropped only on TLS-protected connection. I don't know how to implement `is_tls(self)` as I do not understand wocky library in-depth. I found no easy way to check if TLS-handshake is completed. Can it be done?

I tested the patch with telepathy-gabble=0.18.3-0ubuntu0.1 and it seems to work at first glance.
Comment 20 Leonid Evdokimov 2016-05-18 14:54:32 UTC
Created attachment 123883 [details] [review]
patch for 0.18.3

Cleaned up the patch a bit to use sasl_generate_base64_nonce() for `id` generation as `id` is effectively `nonce`.

Also, I noted that g_random_int() is used for nonce generation and it's not considered secure according to https://developer.gnome.org/glib/stable/glib-Random-Numbers.html
Comment 21 GitLab Migration User 2019-12-03 19:53:03 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/telepathy/telepathy-gabble/issues/163.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.