in kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultAdminServerHandler.java [105:172]
private void doSaslHandshake() throws Exception {
File keytabFile = new File(adminServerContext.getConfig().getKeyTabFile());
String principal = adminServerContext.getConfig().getProtocol() + "/"
+ adminServerContext.getConfig().getAdminHost();
String fixedPrincipal = AdminServerUtil.fixPrincipal(principal, adminServerContext.getAdminServerSetting());
String adminPrincipal = KrbUtil.makeKadminPrincipal(
adminServerContext.getAdminServerSetting().getKdcRealm()).getName();
Subject subject = AuthUtil.loginUsingKeytab(fixedPrincipal, keytabFile);
Subject.doAs(subject, (PrivilegedExceptionAction<Object>) () -> {
boolean success = false;
try {
ByteBuffer message;
try {
message = transport.receiveMessage();
} catch (SocketTimeoutException ignore) {
// Ignore time out, wake up to see if should continue to run.
// When client create a new tpc transport, socket always timeout,
// because the first connection will not send message to the server.
// SASL handshake is not performed until the connection is established.
return null;
}
Map<String, Object> props = new HashMap<>();
props.put(Sasl.QOP, "auth-conf");
props.put(Sasl.SERVER_AUTH, "true");
String protocol = adminServerContext.getConfig().getProtocol();
String serverName = adminServerContext.getConfig().getServerName();
CallbackHandler callbackHandler = new SaslGssCallbackHandler(adminPrincipal);
SaslServer saslServer = Sasl.createSaslServer(MECHANISM, protocol,
serverName, props, callbackHandler);
if (saslServer == null) {
throw new Exception("Unable to find server implementation for: GSSAPI");
}
setSaslServerWrapper(SaslWrapper.create(saslServer));
while (!saslServer.isComplete()) {
int scComplete = message.getInt();
if (scComplete == NegotiationStatus.SUCCESS.getValue()) {
logger.info("Sasl Client completed");
}
byte[] challenge = null;
try {
challenge = SaslUtils.evaluateResponse(saslServer, message);
} catch (SaslException e) {
throw new Exception("Sasl server evaluate challenge failed. " + e);
}
if (!saslServer.isComplete()) {
// Send message to client only when SASL server is not complete
sendMessage(challenge, saslServer);
logger.info("Waiting receive message");
message = transport.receiveMessage();
}
}
success = true;
} finally {
if (!success) {
transport.release();
}
}
return null;
});
}