powered by Jive Software

Nonexistant account vs wrong password

I’‘m trying to write a custom jabber client which is connecting to a jabberd2 server. When the XMPPConnection.login method fails I can’‘t see a good way of determining whether it’‘s because the username does not exist or because the password is wrong. In both cases, the XMPPError is just a 401 with no additional information. I can create a new account with the AccountManager, but of course I don’‘t want to create accounts every time a user doesn’'t notice he may a typo in his username.

As a temporary solution I’‘ve modified the XMPPConnection.login method so the errors are different, but I don’‘t like that because 1) it kind of defeats the purpose of using the code library and 2) it looks really inelegant. (I’‘m also not at all sure I’‘ll see the same behavior with other servers, but for me that probably isn’'t an issue).

Is there a good way of distinguishing between these cases with the libraries as the exist? If not, any chance there soon will be? Below is my modified version of the method.

George

public synchronized void login(String username, String password, String resource)

throws XMPPException

{

if (!isConnected()) {

throw new IllegalStateException(“Not connected to server.”);

}

if (authenticated) {

throw new IllegalStateException(“Already logged in to server.”);

}

// If we send an authentication packet in “get” mode with just the username,

// the server will return the list of authentication protocols it supports.

Authentication discoveryAuth = new Authentication();

discoveryAuth.setType(IQ.Type.GET);

discoveryAuth.setUsername(username);

PacketCollector collector = packetReader.createPacketCollector(

new PacketIDFilter(discoveryAuth.getPacketID()));

// Send the packet

packetWriter.sendPacket(discoveryAuth);

// Wait up to five seconds for a response from the server.

IQ response = (IQ)collector.nextResult(5000);

if (response == null) {

throw new XMPPException(“No response from the server.”);

}

// If the server replied with an error, throw an exception.

else if (response.getType() == IQ.Type.ERROR) {

XMPPError errXMPP = new XMPPError(401,“Account does not exist”);//GW;

//throw new XMPPException(response.getError());

throw new XMPPException(errXMPP);

}

// Otherwise, no error so continue processing.

Authentication authTypes = (Authentication)response;

collector.cancel();

// Now, create the authentication packet we’'ll send to the server.

Authentication auth = new Authentication();

auth.setUsername(username);

// Figure out if we should use digest or plain text authentication.

if (authTypes.getDigest() != null) {

auth.setDigest(connectionID, password);

}

else if (authTypes.getPassword() != null) {

auth.setPassword(password);

}

else {

throw new XMPPException(“Server does not support compatible authentication mechanism.”);

}

auth.setResource(resource);

collector = packetReader.createPacketCollector(new PacketIDFilter(auth.getPacketID()));

// Send the packet.

packetWriter.sendPacket(auth);

// Wait up to five seconds for a response from the server.

response = (IQ)collector.nextResult(5000);

if (response == null) {

throw new XMPPException(“Authentication failed.”);

}

else if (response.getType() == IQ.Type.ERROR) {

XMPPError errXMPP = new XMPPError(401,“Wrong Password”);//GW

throw new XMPPException(errXMPP);

// throw new XMPPException(response.getError());

}

//no more changes below here