diff --git a/hsarjcli/.classpath b/hsarjcli/.classpath index 18d70f0..30d5f00 100644 --- a/hsarjcli/.classpath +++ b/hsarjcli/.classpath @@ -2,5 +2,9 @@ + + + + diff --git a/hsarjcli/lib/commons-cli-1.2.jar b/hsarjcli/lib/commons-cli-1.2.jar new file mode 100644 index 0000000..3426395 Binary files /dev/null and b/hsarjcli/lib/commons-cli-1.2.jar differ diff --git a/hsarjcli/lib/ws-commons-util-1.0.1.jar b/hsarjcli/lib/ws-commons-util-1.0.1.jar new file mode 100644 index 0000000..8cc8fb4 Binary files /dev/null and b/hsarjcli/lib/ws-commons-util-1.0.1.jar differ diff --git a/hsarjcli/lib/xmlrpc-client-3.1.jar b/hsarjcli/lib/xmlrpc-client-3.1.jar new file mode 100644 index 0000000..b4c0071 Binary files /dev/null and b/hsarjcli/lib/xmlrpc-client-3.1.jar differ diff --git a/hsarjcli/lib/xmlrpc-common-3.1.jar b/hsarjcli/lib/xmlrpc-common-3.1.jar new file mode 100644 index 0000000..fd6d192 Binary files /dev/null and b/hsarjcli/lib/xmlrpc-common-3.1.jar differ diff --git a/hsarjcli/src/de/hsadmin/cli/HSadmin.java b/hsarjcli/src/de/hsadmin/cli/HSadmin.java index 47f3191..66c4c98 100644 --- a/hsarjcli/src/de/hsadmin/cli/HSadmin.java +++ b/hsarjcli/src/de/hsadmin/cli/HSadmin.java @@ -323,6 +323,12 @@ public class HSadmin { 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); diff --git a/hsarjcli/src/de/hsadmin/cli/Scripting.java b/hsarjcli/src/de/hsadmin/cli/Scripting.java new file mode 100644 index 0000000..e0276e0 --- /dev/null +++ b/hsarjcli/src/de/hsadmin/cli/Scripting.java @@ -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()); + } + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/CASTicket.java b/hsarjcli/src/de/hsadmin/jscli/CASTicket.java new file mode 100644 index 0000000..d4a0987 --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/CASTicket.java @@ -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; + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java b/hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java new file mode 100644 index 0000000..f69843c --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/CommandlineParser.java @@ -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); + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/Config.java b/hsarjcli/src/de/hsadmin/jscli/Config.java new file mode 100644 index 0000000..e5936d9 --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/Config.java @@ -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(); + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/JSCliException.java b/hsarjcli/src/de/hsadmin/jscli/JSCliException.java new file mode 100644 index 0000000..c511317 --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/JSCliException.java @@ -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); + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/Main.java b/hsarjcli/src/de/hsadmin/jscli/Main.java new file mode 100644 index 0000000..4ac82b2 --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/Main.java @@ -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 methods = client.listMethods(); + for (String m : methods) { + System.out.println(m); + } + } catch (JSCliException e) { + System.err.println(e.getMessage()); + System.exit(-1); + } + } + +} diff --git a/hsarjcli/src/de/hsadmin/jscli/RpcClient.java b/hsarjcli/src/de/hsadmin/jscli/RpcClient.java new file mode 100644 index 0000000..b4d86bf --- /dev/null +++ b/hsarjcli/src/de/hsadmin/jscli/RpcClient.java @@ -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 listMethods() throws JSCliException { + List methodList = new ArrayList(); + List execute = execute(); + for (Object obj : execute) { + methodList.add(obj.toString()); + } + return methodList; + } + + private List execute() throws JSCliException { + return execute(new ArrayList()); + } + + private List execute(List params) throws JSCliException { + try { + Object execute = client.execute("system.listMethods", params); + ArrayList list = new ArrayList(); + 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); + } + } + +} diff --git a/hsarjcli/src/tools/InstallCert.java b/hsarjcli/src/tools/InstallCert.java new file mode 100644 index 0000000..4d36b6b --- /dev/null +++ b/hsarjcli/src/tools/InstallCert.java @@ -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); + } + } +}