int LoginTask::handleStanza(Stanza& stanza, StanzaHandlerResult& result) { int ok = 1; switch(nPhase_) { case StreamOpen: // <stream:stream xmlns:stream='http://etherx.jabber.org/streams' id='43956666' xmlns='jabber:client' from='user.virtual-presence.org'> if (stanza.getName() == "stream:stream") { result.stanzaHandled(1); result.stanzaConsumed(1); sStreamId_ = stanza.getAttribute("id").getValue(); if (sStreamId_.empty()) { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "<stream:stream> No stream ID")); nPhase_ = LoginFailed; result.connectionFinished(1); result.taskFinished(1); pClient_->onProtocolStartFailed(); } else { sendAuthMechQuery(); nPhase_ = AuthMechanisms; pClient_->onProtocolStart(); } } break; case AuthMechanisms: if (stanza.getName() == "iq") { // <iq id='1' type='result'><query xmlns='jabber:iq:auth'><username>lluna_484de02a54c5</username><digest/><password/><resource/></query></iq> if (sId_ == stanza.getAttribute("id").getValue()) { result.stanzaHandled(1); result.stanzaConsumed(1); String sType = stanza.getAttribute("type").getValue(); if (sType == "error") { String sError; int nError = 0; if (stanza.getError(nError, sError)) { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "jabber:iq:auth error result: %d %s", nError, _sz(sError))); } else { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "jabber:iq:auth unknown error result")); } nPhase_ = LoginFailed; result.connectionFinished(1); pClient_->onProtocolLoginFailed(); } else { Apollo::XMLNode& query = stanza.getChildRef("query"); Apollo::XMLNode& digest = query.getChildRef("digest"); Apollo::XMLNode& password = query.getChildRef("password"); AP_UNUSED_VARIABLE Apollo::XMLNode& resource = query.getChildRef("resource"); if (digest) { sendDigestAuth(); nPhase_ = DigestAuth; } else if (password) { sendPasswordAuth(); nPhase_ = PasswordAuth; } else { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "jabber:iq:auth result: neither digest nor password auth available")); nPhase_ = LoginFailed; result.connectionFinished(1); pClient_->onProtocolLoginFailed(); } } } } break; case DigestAuth: if (stanza.getName() == "iq") { // <iq id='2' type='result'/> if (sId_ == stanza.getAttribute("id").getValue()) { result.stanzaHandled(1); result.stanzaConsumed(1); result.taskFinished(1); String sType = stanza.getAttribute("type").getValue(); if (sType == "error") { String sError; int nError = 0; if (stanza.getError(nError, sError)) { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "DigestAuth error result: %d %s", nError, _sz(sError))); } else { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "DigestAuth unknown error result")); } nPhase_ = LoginFailed; result.connectionFinished(1); pClient_->onProtocolLoginFailed(); } else { apLog_Info((LOG_CHANNEL, LOG_CONTEXT, "Logged in")); nPhase_ = LoggedIn; pClient_->onProtocolLogin(); } } } break; case PasswordAuth: if (stanza.getName() == "iq") { // <iq id='2' type='result'/> if (sId_ == stanza.getAttribute("id").getValue()) { result.stanzaHandled(1); result.stanzaConsumed(1); result.taskFinished(1); String sType = stanza.getAttribute("type").getValue(); if (sType == "error") { String sError; int nError = 0; if (stanza.getError(nError, sError)) { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "PasswordAuth error result: %d %s", nError, _sz(sError))); } else { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "PasswordAuth unknown error result")); } nPhase_ = LoginFailed; result.connectionFinished(1); pClient_->onProtocolLoginFailed(); } else { apLog_Info((LOG_CHANNEL, LOG_CONTEXT, "Logged in")); nPhase_ = LoggedIn; pClient_->onProtocolLogin(); } } } break; case LoginFailed: apLog_Warning((LOG_CHANNEL, LOG_CONTEXT, "Ignoring stanza after LoginFailed")); result.connectionFinished(1); break; default: apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "Unknown phase")); result.connectionFinished(1); } return ok; }