HSAdmin Backend Domains, E-Mail, Datenbanken
Peter Hormanns
2012-07-23 eb2800ad1ceec2c6e677e10bd6f5f3f069b42979
starting point for a scriptable hsadmin client 
12 files added
2 files modified
502 ■■■■■ changed files
hsarjcli/.classpath 4 ●●●● patch | view | raw | blame | history
hsarjcli/lib/commons-cli-1.2.jar patch | view | raw | blame | history
hsarjcli/lib/ws-commons-util-1.0.1.jar patch | view | raw | blame | history
hsarjcli/lib/xmlrpc-client-3.1.jar patch | view | raw | blame | history
hsarjcli/lib/xmlrpc-common-3.1.jar patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/cli/HSadmin.java 6 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/cli/Scripting.java 21 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/CASTicket.java 99 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java 59 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/Config.java 53 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/JSCliException.java 16 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/Main.java 24 ●●●●● patch | view | raw | blame | history
hsarjcli/src/de/hsadmin/jscli/RpcClient.java 61 ●●●●● patch | view | raw | blame | history
hsarjcli/src/tools/InstallCert.java 159 ●●●●● patch | view | raw | blame | history
hsarjcli/.classpath
@@ -2,5 +2,9 @@
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
    <classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
    <classpathentry kind="lib" path="lib/xmlrpc-client-3.1.jar"/>
    <classpathentry kind="lib" path="lib/xmlrpc-common-3.1.jar"/>
    <classpathentry kind="lib" path="lib/ws-commons-util-1.0.1.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>
hsarjcli/lib/commons-cli-1.2.jar
Binary files differ
hsarjcli/lib/ws-commons-util-1.0.1.jar
Binary files differ
hsarjcli/lib/xmlrpc-client-3.1.jar
Binary files differ
hsarjcli/lib/xmlrpc-common-3.1.jar
Binary files differ
hsarjcli/src/de/hsadmin/cli/HSadmin.java
@@ -323,6 +323,12 @@
                new FileInputStream(
                    new File(System.getProperty("user.home"), ".hsadmin.conf")));
        } catch (FileNotFoundException e) {
            try {
                config.load(
                    new FileInputStream(
                        new File("/etc/hsadmin.conf")));
            } catch (FileNotFoundException ee) {
            }
        }
        authenticatedUserName = config.getProperty("userName", System.getenv("USER"));
        loginURL = config.getProperty("loginURL", loginURL);
hsarjcli/src/de/hsadmin/cli/Scripting.java
New file
@@ -0,0 +1,21 @@
package de.hsadmin.cli;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Scripting {
    public static void main(String[] args) {
        ScriptEngineManager engineManager = new ScriptEngineManager();
        ScriptEngine engine = engineManager.getEngineByName("js");
        try {
            engine.eval("var user = { };");
            engine.eval("user['name'] = 'Klaus-Dieter';");
            engine.eval("print(user.name);");
        } catch (ScriptException e) {
            System.err.println(e.getMessage());
        }
    }
}
hsarjcli/src/de/hsadmin/jscli/CASTicket.java
New file
@@ -0,0 +1,99 @@
package de.hsadmin.jscli;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import javax.net.ssl.HttpsURLConnection;
public class CASTicket {
    private static final String LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
    private static final String BACKEND_URL = "https://admin.hostsharing.net:443/hsar/backend";
    private String loginURL;
    private String backendURL;
    private String grantingTicket;
    public CASTicket(String user) throws JSCliException {
        loginURL = Config.getInstance().getProperty("loginURL", LOGIN_URL);
        backendURL = Config.getInstance().getProperty("backendURL", BACKEND_URL);
        grantingTicket = getGrantingTicket(user);
    }
    public String getTicket() throws JSCliException {
        try {
            String encodedParams = URLEncoder.encode("service", "UTF-8")
                    + "=" + URLEncoder.encode(backendURL, "UTF-8");
                return doHttpPost(grantingTicket, encodedParams);
        } catch (UnsupportedEncodingException e) {
            throw new JSCliException(e);
        }
    }
    private String getGrantingTicket(String user) throws JSCliException {
        grantingTicket = null;
        char[] password = null;
        Console console = System.console();
        if (console == null) {
            throw new JSCliException("fatal error: console not found");
        }
        password = console.readPassword("password:");
//        password = "test123".toCharArray();
        if (password == null || password.length <= 0) {
            throw new JSCliException("no password given");
        }
        try {
            String encodedParams = URLEncoder.encode("username", "UTF-8")
                    + "=" + URLEncoder.encode(user, "UTF-8")
                    + "&" + URLEncoder.encode("password", "UTF-8")
                    + "=" + URLEncoder.encode(new String(password), "UTF-8");
            grantingTicket = doHttpPost(loginURL, encodedParams);
        } catch (UnsupportedEncodingException e) {
            throw new JSCliException(e);
        }
        return grantingTicket;
    }
    private String doHttpPost(String urlString, String encodedParams) throws JSCliException {
        String result = null;
        try {
            URL url = new URL(urlString);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setAllowUserInteraction(false);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
            writer.write(encodedParams);
            writer.close();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String ticket = reader.readLine();
            String readLine = null;
            do {
                readLine = reader.readLine();
            } while (readLine != null);
            result = connection.getHeaderField("Location");
            if (ticket != null && ticket.startsWith("ST-")) {
                result = ticket;
            }
        } catch (IOException e) {
            throw new JSCliException(e);
        }
        return result;
    }
    @Override
    public String toString() {
        return grantingTicket;
    }
}
hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java
New file
@@ -0,0 +1,59 @@
package de.hsadmin.jscli;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
public class CommandlineParser {
    private CommandLine cmd;
    private Options opts;
    public CommandlineParser(String[] args) throws JSCliException {
        opts = new Options();
        opts.addOption("h", "help", false, "print this message");
        opts.addOption("u", "user", true, "specify login user");
        opts.addOption("r", "runas", true, "specify run-as user");
        opts.addOption("e", "expr", true, "expression to execute");
        opts.addOption("f", "file", true, "script file to execute");
        PosixParser parser = new PosixParser();
        try {
            if (args.length < 1) {
                printHelp();
                System.exit(0);
            }
            cmd = parser.parse(opts, args);
            if (cmd.hasOption("help")) {
                printHelp();
                System.exit(0);
            }
        } catch (ParseException e) {
            throw new JSCliException(e);
        }
    }
    public String getUser() {
        return cmd.getOptionValue("user", System.getProperty("user.name"));
    }
    public String getRunAs() {
        return cmd.getOptionValue("runas", getUser());
    }
    public String getExpression() {
        return cmd.getOptionValue("expr", null);
    }
    public String getFile() {
        return cmd.getOptionValue("file", null);
    }
    public void printHelp() {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("hsscript", opts);
    }
}
hsarjcli/src/de/hsadmin/jscli/Config.java
New file
@@ -0,0 +1,53 @@
package de.hsadmin.jscli;
import java.io.File;
import java.io.FileReader;
import java.util.Properties;
public class Config {
    private static Config instance;
    private Properties props;
    private Config() {
        props = new Properties();
        File file = new File(System.getProperty("user.dir") + "/hsadmin.properties");
        if (!file.canRead()) {
            file = new File(System.getProperty("user.dir") + "/conf/hsadmin.properties");
        }
        if (!file.canRead()) {
            file = new File(System.getProperty("user.home") + "/.hsadmin.properties");
        }
        if (!file.canRead()) {
            file = new File("/etc/hsadmin.properties");
        }
        if (!file.canRead()) {
            file = new File("/etc/hsadmin/hsadmin.properties");
        }
        if (file.canRead()) {
            try {
                props.load(new FileReader(file));
            } catch (Exception e) {
                // should not happen
                e.printStackTrace();
            }
        }
    }
    public static Config getInstance() {
        if (instance == null) {
            instance = new Config();
        }
        return instance;
    }
    public String getProperty(String propertyName) {
        return props.getProperty(propertyName).trim();
    }
    public String getProperty(String propertyName, String defaultValue) {
        return props.getProperty(propertyName, defaultValue).trim();
    }
}
hsarjcli/src/de/hsadmin/jscli/JSCliException.java
New file
@@ -0,0 +1,16 @@
package de.hsadmin.jscli;
public class JSCliException extends Exception {
    private static final long serialVersionUID = 1L;
    public JSCliException(Exception e) {
        super(e);
    }
    public JSCliException(String message) {
        super(message);
    }
}
hsarjcli/src/de/hsadmin/jscli/Main.java
New file
@@ -0,0 +1,24 @@
package de.hsadmin.jscli;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        try {
            CommandlineParser cmdParser = new CommandlineParser(args);
            String user = cmdParser.getUser();
            CASTicket tgt = new CASTicket(user);
            System.out.println(tgt);
            RpcClient client = new RpcClient(tgt);
            List<String> methods = client.listMethods();
            for (String m : methods) {
                System.out.println(m);
            }
        } catch (JSCliException e) {
            System.err.println(e.getMessage());
            System.exit(-1);
        }
    }
}
hsarjcli/src/de/hsadmin/jscli/RpcClient.java
New file
@@ -0,0 +1,61 @@
package de.hsadmin.jscli;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
public class RpcClient {
    private static final String XMLRPC_URL = "https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin";
    private String xmlrpcURL;
    private XmlRpcClient client;
    public RpcClient(CASTicket tgt) throws JSCliException {
        try {
            xmlrpcURL = Config.getInstance().getProperty("xmlrpcURL", XMLRPC_URL);
            XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
            config.setServerURL(new URL(xmlrpcURL));
            config.setEnabledForExtensions(true);
            client = new XmlRpcClient();
            client.setConfig(config);
        } catch (MalformedURLException e) {
            throw new JSCliException(e);
        }
    }
    public List<String> listMethods() throws JSCliException {
        List<String> methodList = new ArrayList<String>();
        List<Object> execute = execute();
        for (Object obj : execute) {
            methodList.add(obj.toString());
        }
        return methodList;
    }
    private List<Object> execute() throws JSCliException {
        return execute(new ArrayList<Object>());
    }
    private List<Object> execute(List<?> params) throws JSCliException {
        try {
            Object execute = client.execute("system.listMethods", params);
            ArrayList<Object> list = new ArrayList<Object>();
            if (execute instanceof Object[]) {
                Object[] resArray = (Object[]) execute;
                for (int idx=0; idx < resArray.length; idx++) {
                    list.add(resArray[idx]);
                }
            }
            return list;
        } catch (XmlRpcException e) {
            throw new JSCliException(e);
        }
    }
}
hsarjcli/src/tools/InstallCert.java
New file
@@ -0,0 +1,159 @@
package tools;
import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
 * Class used to add the server's certificate to the KeyStore
 * with your trusted certificates.
 */
public class InstallCert {
    public static void main(String[] args) throws Exception {
        String host;
        int port;
        char[] passphrase;
        if ((args.length == 1) || (args.length == 2)) {
            String[] c = args[0].split(":");
            host = c[0];
            port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
            String p = (args.length == 1) ? "changeit" : args[1];
            passphrase = p.toCharArray();
        } else {
            System.out.println("Usage: java InstallCert [:port] [passphrase]");
            return;
        }
        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP
                    + "lib" + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "...");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[]{tm}, null);
        SSLSocketFactory factory = context.getSocketFactory();
        System.out.println("Opening connection to " + host + ":" + port + "...");
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }
        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));
        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println
                    (" " + (i + 1) + " Subject " + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }
        System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }
        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);
        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();
        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out.println
                ("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }
    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }
    private static class SavingTrustManager implements X509TrustManager {
        private final X509TrustManager tm;
        private X509Certificate[] chain;
        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }
        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }
}