powered by Jive Software

Smack MultiUserChat unable to handle captcha challenge on MUC join


#1

Experience the following problem on aTalk to join a chatRoom when server challenge the user with captcha.

Following briefly described the sequence of events:
a. user lepoard sends an invitation to user swordfish to join group chat
b. swordfish accepts the invitation and send a join chatroom <presence/> stanza
c. ejabberd server responses with a captcha challenge to swordfish in a message stanza.
d. however smack MultiUserChat seems unable to receive this message nor process for delivery to aTalk.
e. then smack throws response timeout after 10 seconds with no reply for <presence/> sent earlier.
f. ejabberd server sends the following error message
<error code=‘401’ type=‘auth’><not-authorized xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas’/><text xml:lang=‘en’ xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas’>The CAPTCHA verification has failed</text>

I have checked and confirmed the MultiUserChat is properly initialized and messageListener is being registered. The following messageListener is also not triggered with the received captcha message stanza.

        messageListener = new StanzaListener() {
            @Override
            public void processStanza(Stanza packet) throws NotConnectedException {
                Message message = (Message) packet;
                for (MessageListener listener : messageListeners) {
                    listener.processMessage(message);
                }
            }
        };

Not sure if the above process flow is per xmpp standard. How to get MultiUserChat relay the captcha message to upper application.

======= On Jitsi on ubunut=======
its chat window displays
Your messages to chatroom-zcng@conference.atalk.org are being blocked. To unblock them, visit http://atalk.sytes.net:5280/captcha/15339626552052144487
when the user click the link an enter the correct captcha code, the server responded with ‘The CAPTCHA is valid.’ But seems the user is still unable to send any message to the chatRoom on Jitsi. I did not investigate further whether the server did sent the reply to <presence/> to jitsi client.

[20180714 - upate]
Actually in jitsi, you need to manually launch the chatRoom in a separate window before you are allow to send or receive chatRoom messages.

Also tested on Conversion on android:
It is working and is able to receive and send chat room message on the same chat window, after entered the correct captcha challenge code on web browser.

07-10 14:14:21.555 31074-31175/org.atalk.android D/SMACK: RECV (0): <message to='swordfish@atalk.org/atalk' from='chatroom-zcng@conference.atalk.org'><x xmlns='http://jabber.org/protocol/muc#user'><invite from='leopard@atalk.org/atalk'><reason>Group chat invitation</reason></invite></x><x reason='Group chat invitation' jid='chatroom-zcng@conference.atalk.org' xmlns='jabber:x:conference'/><body xml:lang='en'>leopard@atalk.org/atalk invites you to the room chatroom-zcng@conference.atalk.org (Group chat invitation) </body></message>```

07-10 14:14:22.818 31074-31174/org.atalk.android D/SMACK: SENT (0): <presence to='chatroom-zcng@conference.atalk.org/swordfish' id='Vn8UH-129'><x xmlns='http://jabber.org/protocol/muc'></x><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://android.atalk.org' ver='SPANeHrMhKxipyDRRXFZu1T21So='/><x xmlns='vcard-temp:x:update'><photo>60c4791b27af76cf3e8816b2e35630855e04dd31</photo></x></presence>
07-10 14:14:22.912 31074-31175/org.atalk.android D/SMACK: RECV (0): <message to='swordfish@atalk.org/atalk' from='chatroom-zcng@conference.atalk.org' id='18288713003808171855'><x xmlns='jabber:x:oob'><url>http://atalk.sytes.net:5280/captcha/18288713003808171855</url></x><captcha xmlns='urn:xmpp:captcha'><x type='form' xmlns='jabber:x:data'><field var='FORM_TYPE' type='hidden'><value>urn:xmpp:captcha</value></field><field var='from' type='hidden'><value>chatroom-zcng@conference.atalk.org/swordfish</value></field><field var='challenge' type='hidden'><value>18288713003808171855</value></field><field var='sid' type='hidden'><value>Vn8UH-129</value></field><field var='ocr' type='text-single' label='Enter the text you see'><media xmlns='urn:xmpp:media-element'><uri type='image/png'>cid:sha1+0e34041a59b6e2daef318cfe502f555dd14dc7e4@bob.xmpp.org</uri></media><required/></field></x></captcha><data type='image/png' max-age='0' cid='sha1+0e34041a59b6e2daef318cfe502f555dd14dc7e4@bob.xmpp.org' xmlns='urn:xmpp:bob'>iVBORw0KGgoAAAANSUhEUgAAAIwAAAA8CAAAAACRYQ2XAAAABGdBTUEAALG

UQ5IUR0L6/gBJSj0yG4Dx0DRW85rYzz7eECoyvVGrJFLtJ5Q6a405RpIki0jysiWvvvBj1u2Z3AAAABJRU5ErkJggg==</data><body xml:lang='en'>Your messages to chatroom-zcng@conference.atalk.org are being blocked. To unblock them, visit http://atalk.sytes.net:5280/captcha/5032043024718765253</body></message>
07-10 14:14:32.845 31074-31549/org.atalk.android E/aTalk: [15384] impl.protocol.jabber.ChatRoomJabberImpl.joinAs().573 Failed to join room chatroom-zcng@conference.atalk.org with nickname: swordfish@atalk.org.
    org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 10000ms (~10s). Waited for response using: AndFilter: (StanzaTypeFilter: Presence, OrFilter: (AndFilter: (FromMatchesFilter (ignoreResourcepart): chatroom-zcng@conference.atalk.org, MUCUserStatusCodeFilter: status=110), AndFilter: (FromMatchesFilter (full): chatroom-zcng@conference.atalk.org/swordfish, StanzaIdFilter: id=Vn8UH-129, PresenceTypeFilter: type=error))).
        at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:260)
        at org.jivesoftware.smackx.muc.MultiUserChat.enter(MultiUserChat.java:355)
        at org.jivesoftware.smackx.muc.MultiUserChat.join(MultiUserChat.java:711)
        at org.jivesoftware.smackx.muc.MultiUserChat.join(MultiUserChat.java:603)
        at net.java.sip.communicator.impl.protocol.jabber.ChatRoomJabberImpl.joinAs(ChatRoomJabberImpl.java:539)
        at net.java.sip.communicator.impl.protocol.jabber.ChatRoomJabberImpl.joinAs(ChatRoomJabberImpl.java:588)
        at net.java.sip.communicator.impl.muc.MUCServiceImpl$JoinChatRoomTask.run(MUCServiceImpl.java:523)

07-10 14:16:23.005 31074-31175/org.atalk.android D/SMACK: RECV (0): <presence xml:lang='en' to='swordfish@atalk.org/atalk' from='chatroom-zcng@conference.atalk.org/swordfish' type='error' id='Vn8UH-129'><x xmlns='http://jabber.org/protocol/muc'/><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://android.atalk.org' ver='SPANeHrMhKxipyDRRXFZu1T21So='/><x xmlns='vcard-temp:x:update'><photo>60c4791b27af76cf3e8816b2e35630855e04dd31</photo></x><error code='401' type='auth'><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>The CAPTCHA verification has failed</text></error></presence>

#2

MUC messageListener is not invoked because the captcha hint message is not of type ‘groupchat’. If you want to listenen for this messages, then simply install an appropriate stanza listener.

I am not aware that the “solve captcha before entering a MUC” is standardized (but we really should).


#3

Thank. It was about the same time that I also found the problem. Would you be considered to add this message listener in you muc. Or you prefer to let user do it at XMPPTCPConnection on their own.


#4

I am happy to do what is sensible as soon as there is an open standard describing the procedure.


#5

I believe ejabberd has implemented per the standard below
https://xmpp.org/extensions/xep-0158.html

Temporary for aTalk, I have implemented the following and tested working:

    public ChatRoomJabberImpl(MultiUserChat multiUserChat, ProtocolProviderServiceJabberImpl provider)
    {
        mMultiUserChat = multiUserChat;
        mProvider = provider;

        this.opSetMuc = (OperationSetMultiUserChatJabberImpl) provider.getOperationSet(OperationSetMultiUserChat.class);
        this.oldSubject = multiUserChat.getSubject();
        multiUserChat.addSubjectUpdatedListener(new MucSubjectUpdatedListener());
        multiUserChat.addParticipantStatusListener(new MemberListener());
        multiUserChat.addUserStatusListener(new UserListener());
        final MucMessageListener messageListener = new MucMessageListener();
        multiUserChat.addMessageListener(messageListener);

        presenceInterceptor = new PresenceInterceptor();
        multiUserChat.addPresenceInterceptor(presenceInterceptor);
        participantListener = new ParticipantListener();
        multiUserChat.addParticipantListener(participantListener);
        invitationRejectionListeners = new InvitationRejectionListeners();
        multiUserChat.addInvitationRejectionListener(invitationRejectionListeners);

        // setup message listener to receive presence captcha challenge message
        StanzaFilter fromRoomFilter = FromMatchesFilter.create(multiUserChat.getRoom());
        StanzaFilter fromRoomCaptchaFilter = new AndFilter(fromRoomFilter, MessageTypeFilter.NORMAL);

        provider.getConnection().addAsyncStanzaListener(new StanzaListener()
        {
            @Override
            public void processStanza(Stanza packet)
            {
                messageListener.processMessage((org.jivesoftware.smack.packet.Message) packet);
            }
        }, fromRoomCaptchaFilter);

        ConferenceChatManager conferenceChatManager = AndroidGUIActivator.getUIService().getConferenceChatManager();
        addMessageListener(conferenceChatManager);
    }

#6

Excellent. I have created SMACK-823.