Created
September 14, 2017 18:59
-
-
Save robstryker/556b7a5f296004fdebd441c6702186d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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