package org.jivesoftware.openfire.sasl;
import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.session.LocalSession;
import org.jivesoftware.util.JiveGlobals;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
/**
* Implementation of the SASL ANONYMOUS mechanism.
*
* @author Guus der Kinderen, guus@goodbytes.nl
* @see <a href="http://tools.ietf.org/html/rfc4505">RFC 4505</a>
* @see <a href="http://xmpp.org/extensions/xep-0175.html">XEP 0175</a>
*/
public class AnonymousSaslServer implements SaslServer
{
public static final String NAME = "ANONYMOUS";
private boolean complete = false;
private LocalSession session;
public AnonymousSaslServer( LocalSession session )
{
this.session = session;
}
@Override
public String getMechanismName()
{
return NAME;
}
@Override
public byte[] evaluateResponse( byte[] response ) throws SaslException
{
if ( isComplete() )
{
throw new IllegalStateException( "Authentication exchange already completed." );
}
complete = true;
// Verify server-wide policy.
if ( !JiveGlobals.getBooleanProperty( "xmpp.auth.anonymous" ) )
{
throw new SaslException( "Authentication failed" );
}
// Verify that client can connect from his IP address.
final boolean forbidAccess = !LocalClientSession.isAllowedAnonymous( session.getConnection() );
if ( forbidAccess )
{
throw new SaslException( "Authentication failed" );
}
// Just accept the authentication :)
return null;
}
@Override
public boolean isComplete()
{
return complete;
}
@Override
public String getAuthorizationID()
{
if ( !isComplete() )
{
throw new IllegalStateException( "Authentication exchange not completed." );
}
return null; // Anonymous!
}
@Override
public byte[] unwrap( byte[] incoming, int offset, int len ) throws SaslException
{
if ( !isComplete() )
{
throw new IllegalStateException( "Authentication exchange not completed." );
}
throw new IllegalStateException( "SASL Mechanism '" + getMechanismName() + " does not support integrity nor privacy." );
}
@Override
public byte[] wrap( byte[] outgoing, int offset, int len ) throws SaslException
{
if ( !isComplete() )
{
throw new IllegalStateException( "Authentication exchange not completed." );
}
throw new IllegalStateException( "SASL Mechanism '" + getMechanismName() + " does not support integrity nor privacy." );
}
@Override
public Object getNegotiatedProperty( String propName )
{
if ( !isComplete() )
{
throw new IllegalStateException( "Authentication exchange not completed." );
}
if ( propName.equals( Sasl.QOP ) )
{
return "auth";
}
else
{
return null;
}
}
@Override
public void dispose() throws SaslException
{
complete = false;
session = null;
}
}