/** * Notification message saying that SASL authentication was successful. The next step * would be to bind the resource. * @throws SmackException */ public void authenticated(Success success) throws SmackException { // RFC6120 6.3.10 "At the end of the authentication exchange, the SASL server (the XMPP // "receiving entity") can include "additional data with success" if appropriate for the // SASL mechanism in use. In XMPP, this is done by including the additional data as the XML // character data of the <success/> element." The used SASL mechanism should be able to // verify the data send by the server in the success stanza, if any. if (success.getData() != null) { challengeReceived(success.getData(), true); } currentMechanism.checkIfSuccessfulOrThrow(); authenticationSuccessful = true; // Wake up the thread that is waiting in the #authenticate method synchronized (this) { notify(); } }
/** * Parse the received packets and notify the corresponding connection. * * @param event the BOSH client response which includes the received packet. */ public void responseReceived(BOSHMessageEvent event) { AbstractBody body = event.getBody(); if (body != null) { try { if (sessionID == null) { sessionID = body.getAttribute(BodyQName.create(XMPPBOSHConnection.BOSH_URI, "sid")); } if (streamId == null) { streamId = body.getAttribute(BodyQName.create(XMPPBOSHConnection.BOSH_URI, "authid")); } final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new StringReader(body.toXML())); int eventType = parser.getEventType(); do { eventType = parser.next(); switch (eventType) { case XmlPullParser.START_TAG: String name = parser.getName(); switch (name) { case Message.ELEMENT: case IQ.IQ_ELEMENT: case Presence.ELEMENT: parseAndProcessStanza(parser); break; case "challenge": // The server is challenging the SASL authentication // made by the client final String challengeData = parser.nextText(); getSASLAuthentication().challengeReceived(challengeData); break; case "success": send(ComposableBody.builder().setNamespaceDefinition("xmpp", XMPPBOSHConnection.XMPP_BOSH_NS).setAttribute( BodyQName.createWithPrefix(XMPPBOSHConnection.XMPP_BOSH_NS, "restart", "xmpp"), "true").setAttribute( BodyQName.create(XMPPBOSHConnection.BOSH_URI, "to"), getServiceName()).build()); Success success = new Success(parser.nextText()); getSASLAuthentication().authenticated(success); break; case "features": parseFeatures(parser); break; case "failure": if ("urn:ietf:params:xml:ns:xmpp-sasl".equals(parser.getNamespace(null))) { final SASLFailure failure = PacketParserUtils.parseSASLFailure(parser); getSASLAuthentication().authenticationFailed(failure); } break; case "error": throw new StreamErrorException(PacketParserUtils.parseStreamError(parser)); } break; } } while (eventType != XmlPullParser.END_DOCUMENT); } catch (Exception e) { if (isConnected()) { notifyConnectionError(e); } } } }