package org.corfudb.security.sasl.plaintext;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import lombok.extern.slf4j.Slf4j;
/**
* Created by sneginhal on 01/31/2017.
* This is the server side of SASL Plain Text authentication.
* This SimpleChannelInboundHandler is inserted in the CorfuServer's Netty
* pipeline. Once TLS is negotiated and we have a secure channel, this handler
* expects the username/password from the remote end as per:
* https://tools.ietf.org/html/rfc4616
*/
@Slf4j
public class PlainTextSaslNettyServer extends SimpleChannelInboundHandler<ByteBuf> {
private SaslServer saslServer;
private final String mechanisms = "PLAIN";
static {
PlainTextSaslServerProvider.initialize();
}
public PlainTextSaslNettyServer() throws SaslException {
saslServer = Sasl.createSaslServer(mechanisms, "plain", null, null, null);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf)
throws Exception {
byte[] msg = new byte[buf.readableBytes()];
buf.getBytes(0, msg);
while (!saslServer.isComplete()) {
try {
byte[] challenge = saslServer.evaluateResponse(msg);
} catch (SaslException se) {
log.error("SaslException {}", se.toString());
break;
}
}
if (saslServer.isComplete()) {
ctx.pipeline().remove(this);
}
}
}