Skip to content

Instantly share code, notes, and snippets.

@robstryker
Created September 14, 2017 18:59
Show Gist options
  • Save robstryker/556b7a5f296004fdebd441c6702186d9 to your computer and use it in GitHub Desktop.
Save robstryker/556b7a5f296004fdebd441c6702186d9 to your computer and use it in GitHub Desktop.
import java.io.IOException;
import java.util.Collections;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.RealmCallback;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.ModelControllerClientConfiguration;
import org.jboss.as.controller.client.helpers.standalone.ServerDeploymentManager;
import org.jboss.dmr.ModelNode;
import org.wildfly.security.auth.callback.CallbackUtil;
import org.wildfly.security.auth.callback.CredentialCallback;
import org.wildfly.security.auth.callback.OptionalNameCallback;
import org.wildfly.security.credential.PasswordCredential;
import org.wildfly.security.password.interfaces.ClearPassword;
import org.wildfly.security.password.interfaces.DigestPassword;
import org.wildfly.security.util.CodePointIterator;
public class MyMain {
private static ModelControllerClient client;
private static ServerDeploymentManager manager;
public static void main(String[] args) {
try {
ModelControllerClientConfiguration config = new ModelControllerClientConfiguration.Builder()
.setHostName("localhost")
.setPort(9990)
.setHandler(getCallbackHandler())
.setProtocol("http-remoting")
.setConnectionTimeout(10000)
.setSaslOptions(Collections.emptyMap())
.build();
client = ModelControllerClient.Factory.create(config);
manager = ServerDeploymentManager.Factory.create(client);
System.out.println(getServerState());
//stopServer();
} catch (RuntimeException uhe) {
throw new RuntimeException(uhe);
}
}
public static final String OP = "operation";
public static final String SHUTDOWN = "shutdown";
public static void stopServer() throws RuntimeException {
ModelNode request = new ModelNode();
request.get(OP).set(SHUTDOWN);
quietlyExecute(request);
}
// this should only be used when doing shutdown and restart operations.
private static void quietlyExecute(ModelNode node) throws RuntimeException {
try {
client.execute(node);
} catch (Exception e) {
// During shutdown, some connections may be closed prematurely
// It is acceptable to ignore these errors.
if (!isConnectionCloseException(e)) {
throw new RuntimeException(e);
}
}
}
public static final String READ_ATTRIBUTE_OPERATION = "read-attribute";
public static final String NAME = "name";
public static final String SERVER_STATE = "server-state";
public static final String ADDRESS = "address";
public static final String FAILURE_DESCRIPTION = "failure-description";
public static final String RESULT = "result";
public static final String OUTCOME = "outcome";
public static final String SUCCESS = "success";
public static String getServerState() throws RuntimeException {
ModelNode request = new ModelNode();
request.get(OP).set(READ_ATTRIBUTE_OPERATION);
request.get(NAME).set(SERVER_STATE);
ModelNode response = execute(request);
return response.asString();
}
/*package*/ static ModelNode execute(ModelNode node) throws RuntimeException {
try {
ModelNode response = client.execute(node);
if (!isSuccess(response)) {
throw new RuntimeException(
"Could not execute " + node.get(OP) + " for " + node.get(ADDRESS) + ". Failure was " + response.get(FAILURE_DESCRIPTION));
}
return response.get(RESULT);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static boolean isSuccess(ModelNode operationResult) {
if (operationResult != null) {
ModelNode outcome = operationResult.get(OUTCOME);
return outcome != null && outcome.asString().equals(SUCCESS);
}
return false;
}
private static boolean isConnectionCloseException(Exception e) {
return (e instanceof IOException
&& e.getMessage() != null
&& (e.getMessage().indexOf("Channel closed") > -1) // pre-AS 7.1 client lib
|| e.getMessage().indexOf("Operation failed") > -1); // AS 7.1 client lib
}
protected static CallbackHandler getCallbackHandler() {
return new ToolsWF11CallbackHandler();
}
protected static class ToolsWF11CallbackHandler implements CallbackHandler {
private String realm;
protected RealmCallback getRealmCallback(Callback[] cbs) {
for( int i = 0; i < cbs.length; i++ ) {
if( cbs[i] instanceof RealmCallback)
return (RealmCallback)cbs[i];
}
return null;
}
protected NameCallback getNameCallback(Callback[] cbs) {
for( int i = 0; i < cbs.length; i++ ) {
if( cbs[i] instanceof NameCallback)
return (NameCallback)cbs[i];
}
return null;
}
protected CredentialCallback getCredentialCallback(Callback[] cbs) {
for( int i = 0; i < cbs.length; i++ ) {
if( cbs[i] instanceof CredentialCallback)
return (CredentialCallback)cbs[i];
}
return null;
}
protected PasswordCallback getPasswordCallback(Callback[] cbs) {
for( int i = 0; i < cbs.length; i++ ) {
if( cbs[i] instanceof PasswordCallback)
return (PasswordCallback)cbs[i];
}
return null;
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
RealmCallback rcb = getRealmCallback(callbacks);
if( rcb != null ) {
realm = rcb.getPrompt();
String defaultText = rcb.getDefaultText();
rcb.setText(defaultText); // For now just use the realm suggested.
}
NameCallback ncb = getNameCallback(callbacks);
if( ncb instanceof OptionalNameCallback) {
// No credentials need to be set...
return;
}
PasswordCallback passCB = getPasswordCallback(callbacks);
CredentialCallback credCB = getCredentialCallback(callbacks);
if( ncb instanceof OptionalNameCallback) {
((NameCallback) callbacks[0]).setName("anonymous JBossTools user");
return;
}
String passPrompt = (passCB == null ? "Password" : passCB.getPrompt());
String[] results = new String[] {"user","pass"};
if( results != null && results.length >= 2 ) {
String u = results[0];
String p = results[1];
ncb.setName(results[0]);
if( passCB != null ) {
passCB.setPassword(p.toCharArray());
} else if( credCB != null ) {
String digest = null;
if (digest == null && credCB.isCredentialTypeSupported(PasswordCredential.class, ClearPassword.ALGORITHM_CLEAR)) {
credCB.setCredential(new PasswordCredential(ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, p.toCharArray())));
} else if (digest != null && credCB.isCredentialTypeSupported(PasswordCredential.class, DigestPassword.ALGORITHM_DIGEST_MD5)) {
// We don't support an interactive use of this callback so it must have been set in advance.
final byte[] bytes = CodePointIterator.ofString(digest).hexDecode().drain();
credCB.setCredential(new PasswordCredential(DigestPassword.createRaw(DigestPassword.ALGORITHM_DIGEST_MD5, u, realm, bytes)));
} else {
CallbackUtil.unsupported(credCB);
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment