package org.jivesoftware.openfire.plugin.ofmeet.sasl;
import org.jivesoftware.openfire.plugin.ofmeet.TokenManager;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import java.security.Principal;
/**
* A SaslServer implementation that is specific to OfMeet.
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class OfMeetSaslServer implements SaslServer
{
public static final String MECHANISM_NAME = "OFMEET";
private String authorizationID = null;
private TokenManager tokenManager;
public OfMeetSaslServer( TokenManager tokenManager )
{
this.tokenManager = tokenManager;
}
@Override
public String getMechanismName()
{
return MECHANISM_NAME;
}
@Override
public byte[] evaluateResponse( byte[] response ) throws SaslException
{
if ( response == null )
{
throw new IllegalArgumentException( "Argument 'response' cannot be null." );
}
final String decoded;
try
{
decoded = new String( response, "UTF-8" );
}
catch ( Exception ex )
{
throw new SaslException( "Unable to decode client response.", ex );
}
final Principal principal = tokenManager.validate( decoded );
if ( principal == null )
{
throw new SaslException( "Client response contained an invalid token." );
}
else
{
authorizationID = principal.getName();
if ( authorizationID == null || authorizationID.isEmpty() )
{
throw new IllegalStateException(); // This should not happen. You're either authenticated, or not.
}
}
return null;
}
public boolean isComplete()
{
return true;
}
public String getAuthorizationID()
{
if ( !isComplete() )
{
throw new IllegalStateException( MECHANISM_NAME + " authentication has not completed." );
}
return authorizationID;
}
public Object getNegotiatedProperty( String propName )
{
if ( !isComplete() )
{
throw new IllegalStateException( MECHANISM_NAME + " authentication has not completed." );
}
if ( Sasl.QOP.equals( propName ) )
{
return "auth";
}
return null;
}
public void dispose() throws SaslException
{
authorizationID = null;
tokenManager = null;
}
public byte[] unwrap( byte[] incoming, int offset, int len ) throws SaslException
{
if ( !isComplete() )
{
throw new IllegalStateException( MECHANISM_NAME + " authentication has not completed." );
}
throw new IllegalStateException( MECHANISM_NAME + " supports neither integrity nor privacy." );
}
public byte[] wrap( byte[] outgoing, int offset, int len ) throws SaslException
{
if ( !isComplete() )
{
throw new IllegalStateException( MECHANISM_NAME + " authentication has not completed." );
}
throw new IllegalStateException( MECHANISM_NAME + " supports neither integrity nor privacy." );
}
}