From 61366ba8efcc0cf3d36438e9ee26228e7bc66174 Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 12 Jun 2009 12:42:05 +0000 Subject: BKU Web Start git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@361 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/bku/webstart/BKULauncher.java | 339 +++++++++++++++------ .../src/main/java/at/gv/egiz/bku/webstart/CA.java | 117 ------- .../java/at/gv/egiz/bku/webstart/Container.java | 60 ++-- .../java/at/gv/egiz/bku/webstart/TLSServerCA.java | 138 +++++++++ .../at/gv/egiz/bku/webstart/ui/TrayIconDialog.java | 9 +- BKUWebStart/src/main/jnlp/resources/img/logo.png | Bin 0 -> 2609 bytes .../src/main/jnlp/resources/img/logo_64x64.png | Bin 0 -> 2299 bytes .../src/main/jnlp/resources/img/logo_90x90.png | Bin 0 -> 3294 bytes BKUWebStart/src/main/jnlp/resources/img/splash.png | Bin 0 -> 54978 bytes .../src/main/jnlp/resources/img/version.xml | 17 ++ BKUWebStart/src/main/jnlp/resources/logo.png | Bin 2609 -> 0 bytes BKUWebStart/src/main/jnlp/resources/logo_64x64.png | Bin 2299 -> 0 bytes BKUWebStart/src/main/jnlp/resources/logo_90x90.png | Bin 3294 -> 0 bytes BKUWebStart/src/main/jnlp/resources/splash.png | Bin 54978 -> 0 bytes BKUWebStart/src/main/jnlp/resources/version.xml | 186 +++++++++++ BKUWebStart/src/main/jnlp/template.xml | 13 +- .../resources/at/gv/egiz/bku/webstart/ui/logo.png | Bin 1751 -> 0 bytes .../at/gv/egiz/bku/webstart/ui/trayicon.png | Bin 0 -> 2609 bytes BKUWebStart/src/main/resources/logo.png | Bin 2299 -> 0 bytes BKUWebStart/src/main/resources/splash.png | Bin 54978 -> 0 bytes 20 files changed, 640 insertions(+), 239 deletions(-) delete mode 100644 BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java create mode 100644 BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java create mode 100644 BKUWebStart/src/main/jnlp/resources/img/logo.png create mode 100644 BKUWebStart/src/main/jnlp/resources/img/logo_64x64.png create mode 100644 BKUWebStart/src/main/jnlp/resources/img/logo_90x90.png create mode 100644 BKUWebStart/src/main/jnlp/resources/img/splash.png create mode 100644 BKUWebStart/src/main/jnlp/resources/img/version.xml delete mode 100644 BKUWebStart/src/main/jnlp/resources/logo.png delete mode 100644 BKUWebStart/src/main/jnlp/resources/logo_64x64.png delete mode 100644 BKUWebStart/src/main/jnlp/resources/logo_90x90.png delete mode 100644 BKUWebStart/src/main/jnlp/resources/splash.png create mode 100644 BKUWebStart/src/main/jnlp/resources/version.xml delete mode 100644 BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/logo.png create mode 100644 BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/trayicon.png delete mode 100644 BKUWebStart/src/main/resources/logo.png delete mode 100644 BKUWebStart/src/main/resources/splash.png (limited to 'BKUWebStart/src') diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java index 854e6535..3d09fb00 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java @@ -1,15 +1,23 @@ package at.gv.egiz.bku.webstart; +import iaik.asn1.CodingException; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.MalformedURLException; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -25,16 +33,157 @@ import org.apache.commons.logging.LogFactory; import at.gv.egiz.bku.webstart.ui.BKUControllerInterface; import at.gv.egiz.bku.webstart.ui.TrayIconDialog; import at.gv.egiz.bku.utils.StreamUtil; +import java.awt.Desktop; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.net.URI; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.util.UUID; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.zip.ZipOutputStream; public class BKULauncher implements BKUControllerInterface { + /** configurations with less than this (major) version will be backuped and updated */ + public static final String MIN_CONFIG_VERSION = "1.0.3"; + public static final String CONFIG_DIR = ".mocca/conf/"; + public static final String CONF_TEMPLATE_FILE = "template.zip"; + public static final String CONF_TEMPLATE_RESOURCE = "at/gv/egiz/bku/webstart/conf/template.zip"; + public static final String WEBAPP_RESOURCE = "BKULocal.war"; + public static final String WEBAPP_FILE = "BKULocal.war"; + public static final String KEYSTORE_FILE = "keystore.ks"; + public static final String MESSAGES_RESOURCE = "at/gv/egiz/bku/webstart/ui/UIMessages"; + public static final String PASSWD_FILE = ".secret"; + /** resource bundle messages */ + public static final String GREETING_CAPTION = "Greetings.Caption"; + public static final String GREETING_MESSAGE = "Greetings.Message"; + public static final String VERSION_FILE = ".version"; private static Log log = LogFactory.getLog(BKULauncher.class); - private ResourceBundle resourceBundle = null; private Container server; -// private SplashScreen splash = SplashScreen.getSplashScreen(); + private void createConfig(File configDir, File versionFile, String version) throws IOException, CertificateException, GeneralSecurityException, KeyStoreException, FileNotFoundException, NoSuchAlgorithmException { + log.debug("creating config directory: " + configDir); + configDir.mkdirs(); + InputStream is = getClass().getClassLoader().getResourceAsStream(CONF_TEMPLATE_RESOURCE); + OutputStream os = new FileOutputStream(new File(configDir, CONF_TEMPLATE_FILE)); + StreamUtil.copyStream(is, os); + os.close(); + File confTemplateFile = new File(configDir, CONF_TEMPLATE_FILE); + unzip(confTemplateFile); + confTemplateFile.delete(); + writeVersionFile(versionFile, version); + } + + private void createCertificates(File configDir) throws IOException, GeneralSecurityException, CodingException { + char[] password = UUID.randomUUID().toString().toCharArray(); + File passwdFile = new File(configDir, PASSWD_FILE); + FileWriter passwdWriter = new FileWriter(passwdFile); + passwdWriter.write(password); + passwdWriter.close(); + if (!passwdFile.setReadable(true, true)) { + passwdFile.delete(); + throw new IOException("failed to make " + passwdFile + " owner readable only, deleting file"); + } + TLSServerCA ca = new TLSServerCA(); + KeyStore ks = ca.generateKeyStore(password); + FileOutputStream fos = new FileOutputStream(new File(configDir, KEYSTORE_FILE)); + ks.store(fos, password); + fos.close(); + } + + private String getFileVersion(File versionFile) throws FileNotFoundException, IOException { + //TODO no file? + if (versionFile.exists() && versionFile.canRead()) { + BufferedReader versionReader = new BufferedReader(new FileReader(versionFile)); + String versionString = null; + while ((versionString = versionReader.readLine().trim()) != null) { + if (versionString.length() > 0 && !versionString.startsWith("#")) { + log.debug("found existing configuration version " + versionString); + break; + } + } + return versionString; + } + return null; + } + + private String getManifestVersion() throws MalformedURLException, IOException { + String bkuWebStartJar = BKULauncher.class.getProtectionDomain().getCodeSource().getLocation().toString(); + URL manifestURL = new URL("jar:" + bkuWebStartJar + "!/META-INF/MANIFEST.MF"); + String version = null; + if (manifestURL != null) { + Manifest manifest = new Manifest(manifestURL.openStream()); + if (log.isTraceEnabled()) { + log.trace("read version information from " + manifestURL); + } + Attributes atts = manifest.getMainAttributes(); + if (atts != null) { + version = atts.getValue("Implementation-Build"); + } + } + if (version == null) { + version = "UNKNOWN"; + } + log.debug("config version: " + version); + return version; + } + + /** + * change the + * @param oldVersion + * @param newVersion + * @return + */ + private boolean updateRequired(String oldVersion, String newVersion) { + if (oldVersion != null) { + int majorEnd = oldVersion.indexOf('-'); + if (majorEnd > 0) { + oldVersion = oldVersion.substring(0, majorEnd); + } + return (oldVersion.compareTo(MIN_CONFIG_VERSION) < 0); + } + log.debug("no old version, update required"); + return true; + } + + private boolean updateRequiredStrict(String oldVersion, String newVersion) { + String[] oldV = oldVersion.split("-"); + String[] newV = newVersion.split("-"); + log.debug("comparing " + oldV[0] + " to " + newV[0]); + if (oldV[0].compareTo(newV[0]) < 0) { + log.debug("update required"); + return true; + } else { + log.debug("comparing " + oldV[oldV.length - 1] + " to " + newV[newV.length - 1]); + if (oldV[oldV.length - 1].compareTo(newV[newV.length - 1]) < 0) { + log.debug("update required"); + return true; + } else { + log.debug("no update required"); + return false; + } + } + } + + private void writeVersionFile(File versionFile, String version) throws IOException { + BufferedWriter versionWriter = new BufferedWriter(new FileWriter(versionFile)); + versionWriter.write("# MOCCA Web Start configuration version\n"); + versionWriter.write("# DO NOT MODIFY THIS FILE\n\n"); + versionWriter.write(version); + versionWriter.close(); + } + +// private SplashScreen splash = SplashScreen.getSplashScreen(); private void startUpServer() throws Exception { + log.info("init servlet container and MOCCA webapp"); server = new Container(); // XmlConfiguration xcfg = new XmlConfiguration(getClass().getClassLoader() // .getResourceAsStream("at/gv/egiz/bku/local/app/jetty.xml")); @@ -44,25 +193,24 @@ public class BKULauncher implements BKUControllerInterface { } private void initTrayIcon() { + log.debug("init MOCCA tray icon"); Locale loc = Locale.getDefault(); try { resourceBundle = ResourceBundle.getBundle( - "at/gv/egiz/bku/webstart/ui/UIMessages", loc); + MESSAGES_RESOURCE, loc); } catch (MissingResourceException mx) { resourceBundle = ResourceBundle.getBundle( - "at/gv/egiz/bku/webstart/ui/UIMessages", Locale.ENGLISH); + MESSAGES_RESOURCE, Locale.ENGLISH); } TrayIconDialog.getInstance().init(resourceBundle); TrayIconDialog.getInstance().setShutdownHook(this); - TrayIconDialog.getInstance().displayInfo("Greetings.Caption", - "Greetings.Message"); + TrayIconDialog.getInstance().displayInfo(GREETING_CAPTION, GREETING_MESSAGE); } private void initStart() { - } - private void initFinished() { + private void initFinished(boolean installCert) { try { // if (splash != null) { // try { @@ -71,34 +219,33 @@ public class BKULauncher implements BKUControllerInterface { // log.warn("Failed to close splash screen: " + ex.getMessage()); // } // } + + log.debug("trying install MOCCA certificate on system browser"); + if (installCert) { + if (Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(new URI("https://localhost:" + + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3496).intValue())); + } catch (Exception ex) { + log.error("failed to open system browser, install MOCCA certificate manually", ex); + } + } else { + log.error("failed to open system browser, install MOCCA certificate manually"); + } + } else { + log.error("failed to open system browser, install MOCCA certificate manually"); + } + } + + log.info("init completed, joining server"); server.join(); } catch (InterruptedException e) { - log.info(e); + log.warn("failed to join MOCCA server: " + e.getMessage(), e); } } -// private void copyDirs(File srcDir, File dstDir) { -// for (File cf : srcDir.listFiles()) { -// File of = new File(dstDir, cf.getName()); -// if (cf.isDirectory()) { -// log.debug("Creating directory: " + of); -// of.mkdir(); -// copyDirs(cf, of); -// } else { -// log.debug("Writing file: " + of); -// try { -// FileInputStream fis = new FileInputStream(cf); -// FileOutputStream fos = new FileOutputStream(of); -// StreamUtil.copyStream(fis, fos); -// fis.close(); -// fos.close(); -// } catch (IOException e) { -// log.error("Cannot copy default configuration", e); -// } -// } -// } -// } - private void unzip(File zipfile) throws IOException { File dir = zipfile.getParentFile(); ZipFile zipFile = new ZipFile(zipfile); @@ -113,73 +260,11 @@ public class BKULauncher implements BKUControllerInterface { File f = new File(eF.getParent()); f.mkdirs(); StreamUtil.copyStream(zipFile.getInputStream(entry), - new FileOutputStream(eF)); + new FileOutputStream(eF)); } zipFile.close(); } - private void checkConfig(String[] args) { -// CommandLineParser parser = new PosixParser(); -// Options options = new Options(); -// options.addOption("c", true, "the configuration's base directory"); -// options.addOption("h", false, "print this message"); -// try { - File cfgDir = new File(System.getProperty("user.home") + "/.mocca/conf"); -// CommandLine cmd = parser.parse(options, args); -// if (cmd.hasOption("h")) { -// HelpFormatter formatter = new HelpFormatter(); -// formatter.printHelp("BKULauncher", options); -// System.exit(0); -// } -// -// if (cmd.hasOption("c")) { -// cfgDir = new File(cmd.getOptionValue("c")); -// } - log.debug("using config directory: " + cfgDir); - if (cfgDir.exists() && cfgDir.isFile()) { - log.error("Configuration directory must not be a file"); - } - if (!cfgDir.exists()) { - log.debug("Creating config directory: " + cfgDir); - cfgDir.mkdirs(); - try { - InputStream is = getClass().getClassLoader().getResourceAsStream( - "at/gv/egiz/bku/webstart/defaultConf/template.zip"); - OutputStream os = new FileOutputStream(new File(cfgDir, - "template.zip")); - StreamUtil.copyStream(is, os); - os.close(); - unzip(new File(cfgDir, "template.zip")); - } catch (IOException iox) { - log.error("Cannot create user directory", iox); - return; - } - CA ca = new CA(); - char[] password = "changeMe".toCharArray(); - KeyStore ks = ca.generateKeyStore(password); - if (ks != null) { - File ksdir = new File(cfgDir, "keystore"); - ksdir.mkdirs(); - FileOutputStream fos; - try { - fos = new FileOutputStream(new File(ksdir, "keystore.ks")); - ks.store(fos, password); - fos.close(); - } catch (Exception e) { - log.error("Cannot store keystore", e); - } - } else { - log.error("Cannot create ssl certificate"); - } - } -// } catch (ParseException e1) { -// log.error(e1); -// HelpFormatter formatter = new HelpFormatter(); -// formatter.printHelp("BKULauncher", options); -// System.exit(0); -// } - } - /** * @param args */ @@ -189,15 +274,74 @@ public class BKULauncher implements BKUControllerInterface { System.setSecurityManager(null); BKULauncher launcher = new BKULauncher(); launcher.initStart(); - launcher.checkConfig(args); + + File configDir = new File(System.getProperty("user.home") + '/' + CONFIG_DIR); + boolean installCert = launcher.ensureConfig(configDir); launcher.startUpServer(); launcher.initTrayIcon(); - launcher.initFinished(); + launcher.initFinished(installCert); } catch (Exception e) { - log.fatal("Cannot launch BKU", e); + log.fatal("Failed to launch BKU: " + e.getMessage(), e); System.exit(-1000); } + } + + private void backupAndDelete(File dir, URI relativeTo, ZipOutputStream zip) throws IOException { + if (dir.isDirectory()) { + File[] subDirs = dir.listFiles(); + for (File subDir : subDirs) { + backupAndDelete(subDir, relativeTo, zip); + subDir.delete(); + } + } else { + URI relativePath = relativeTo.relativize(dir.toURI()); + ZipEntry entry = new ZipEntry(relativePath.toString()); + zip.putNextEntry(entry); + BufferedInputStream entryIS = new BufferedInputStream(new FileInputStream(dir)); + StreamUtil.copyStream(entryIS, zip); + entryIS.close(); + zip.closeEntry(); + dir.delete(); + } + } + /** + * Checks whether the config directory already exists and creates it otherwise. + * @param configDir the config directory to be created + * @return true if a new MOCCA cert was created (and needs to be installed in the browser) + */ + private boolean ensureConfig(File configDir) throws IOException, GeneralSecurityException, CodingException { + log.debug("config directory: " + configDir); + String manifestVersion = getManifestVersion(); + File versionFile = new File(configDir, VERSION_FILE); + + if (configDir.exists()) { + if (configDir.isFile()) { + log.error("invalid config directory: " + configDir); + throw new IOException("invalid config directory: " + configDir); + } else { + String fileVersion = getFileVersion(versionFile); + if (updateRequired(fileVersion, manifestVersion)) { + if (fileVersion == null) { + fileVersion = "unknown"; + } + log.info("updating configuration from " + fileVersion + " to " + manifestVersion); + File moccaDir = configDir.getParentFile(); + File zipFile = new File(moccaDir, "conf-" + fileVersion + ".zip"); + ZipOutputStream zipOS = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + backupAndDelete(configDir, moccaDir.toURI(), zipOS); + zipOS.close(); + createConfig(configDir, versionFile, manifestVersion); + createCertificates(configDir); + return true; + } + } + } else { + createConfig(configDir, versionFile, manifestVersion); + createCertificates(configDir); + return true; + } + return false; } public void shutDown() { @@ -217,5 +361,4 @@ public class BKULauncher implements BKUControllerInterface { } System.exit(0); } - } diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java deleted file mode 100644 index f81d3d83..00000000 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java +++ /dev/null @@ -1,117 +0,0 @@ -package at.gv.egiz.bku.webstart; - -import iaik.asn1.ObjectID; -import iaik.asn1.structures.AlgorithmID; -import iaik.asn1.structures.Name; -import iaik.x509.X509Certificate; -import iaik.x509.extensions.BasicConstraints; -import iaik.x509.extensions.KeyUsage; - -import java.math.BigInteger; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Random; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class CA { - private final static Log log = LogFactory.getLog(CA.class); - - private KeyPair caKeyPair; - private X509Certificate caCert; - - private KeyPair serverKeyPair; - private X509Certificate serverCert; - - public CA() { - } - - private KeyPair generateKeyPair() throws NoSuchAlgorithmException { - KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); - gen.initialize(2048); - return gen.generateKeyPair(); - } - - private void generateCA() throws GeneralSecurityException { - log.debug("Generating CA certificate"); - Name subject = new Name(); - subject.addRDN(ObjectID.country, "AT"); - subject.addRDN(ObjectID.organization, "MOCCA"); - subject.addRDN(ObjectID.organizationalUnit, "MOCCA-CA"); - - caKeyPair = generateKeyPair(); - caCert = new X509Certificate(); - caCert.setSerialNumber(new BigInteger(20, new Random())); - caCert.setSubjectDN(subject); - caCert.setPublicKey(caKeyPair.getPublic()); - caCert.setIssuerDN(subject); - - caCert.addExtension(new BasicConstraints(true)); - caCert.addExtension(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign - | KeyUsage.digitalSignature)); - - GregorianCalendar date = new GregorianCalendar(); - date.add(Calendar.HOUR_OF_DAY, -1); - caCert.setValidNotBefore(date.getTime()); - date.add(Calendar.YEAR, 7); - caCert.setValidNotAfter(date.getTime()); - caCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); - log.debug("Successfully signed CA certificate"); - } - - private void generateServerCert() throws GeneralSecurityException { - log.debug("Generating SSL certificate"); - Name subject = new Name(); - subject.addRDN(ObjectID.country, "AT"); - subject.addRDN(ObjectID.organization, "MOCCA"); - try { - subject.addRDN(ObjectID.commonName, InetAddress.getLocalHost() - .getHostName()); - } catch (UnknownHostException e) { - subject.addRDN(ObjectID.commonName, "localhost"); - } - serverKeyPair = generateKeyPair(); - serverCert = new X509Certificate(); - serverCert.setSerialNumber(new BigInteger(20, new Random())); - serverCert.setSubjectDN(subject); - serverCert.setPublicKey(serverKeyPair.getPublic()); - serverCert.setIssuerDN(caCert.getSubjectDN()); - - serverCert.addExtension(new BasicConstraints(false)); - serverCert.addExtension(new KeyUsage(KeyUsage.keyEncipherment - | KeyUsage.digitalSignature)); - - GregorianCalendar date = new GregorianCalendar(); - date.add(Calendar.HOUR_OF_DAY, -1); - serverCert.setValidNotBefore(date.getTime()); - date.add(Calendar.YEAR, 7); - date.add(Calendar.HOUR_OF_DAY, -1); - serverCert.setValidNotAfter(date.getTime()); - serverCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); - log.debug("Successfully signed server certificate"); - caKeyPair = null; - } - - public KeyStore generateKeyStore(char[] password) { - try { - generateCA(); - generateServerCert(); - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(null, null); - ks.setKeyEntry("server", serverKeyPair.getPrivate(), password, new X509Certificate[]{serverCert, caCert}); - return ks; - } catch (Exception e) { - log.error("Cannot generate certificate", e); - } - return null; - } - -} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java index ef12e4fd..0cd3e633 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java @@ -1,5 +1,15 @@ package at.gv.egiz.bku.webstart; +import at.gv.egiz.bku.utils.StreamUtil; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mortbay.jetty.Connector; @@ -14,8 +24,8 @@ import org.mortbay.thread.QueuedThreadPool; public class Container { - public static final String HTTP_PORT = "mocca.http.port"; - public static final String HTTPS_PORT = "mocca.http.port"; + public static final String HTTP_PORT_PROPERTY = "mocca.http.port"; + public static final String HTTPS_PORT_PROPERTY = "mocca.http.port"; private static Log log = LogFactory.getLog(Container.class); @@ -24,7 +34,7 @@ public class Container { public Container() { } - public void init() { + public void init() throws IOException { server = new Server(); QueuedThreadPool qtp = new QueuedThreadPool(); qtp.setMaxThreads(5); @@ -35,35 +45,51 @@ public class Container { server.setGracefulShutdown(3000); SelectChannelConnector connector = new SelectChannelConnector(); - connector.setPort(Integer.getInteger(HTTP_PORT, 3495).intValue()); + connector.setPort(Integer.getInteger(HTTP_PORT_PROPERTY, 3495).intValue()); connector.setAcceptors(1); - connector.setConfidentialPort(Integer.getInteger(HTTPS_PORT, 3496).intValue()); + connector.setConfidentialPort(Integer.getInteger(HTTPS_PORT_PROPERTY, 3496).intValue()); + connector.setHost("127.0.0.1"); SslSocketConnector sslConnector = new SslSocketConnector(); - sslConnector.setPort(Integer.getInteger(HTTPS_PORT, 3496).intValue()); + sslConnector.setPort(Integer.getInteger(HTTPS_PORT_PROPERTY, 3496).intValue()); sslConnector.setAcceptors(1); - sslConnector.setKeystore(System.getProperty("user.home") - + "/.mocca/conf/keystore/keystore.ks"); - sslConnector.setPassword("changeMe"); - sslConnector.setKeyPassword("changeMe"); + sslConnector.setHost("127.0.0.1"); + File configDir = new File(System.getProperty("user.home") + "/" + BKULauncher.CONFIG_DIR); + sslConnector.setKeystore(configDir.getPath() + "/" + BKULauncher.KEYSTORE_FILE); + File passwdFile = new File(configDir, BKULauncher.PASSWD_FILE); + BufferedReader reader = new BufferedReader(new FileReader(passwdFile)); + String pwd; + while ((pwd = reader.readLine()) != null) { + sslConnector.setPassword(pwd); + sslConnector.setKeyPassword(pwd); + } + reader.close(); server.setConnectors(new Connector[] { connector, sslConnector }); -// HandlerCollection handlers = new HandlerCollection(); WebAppContext webapp = new WebAppContext(); + webapp.setLogUrlOnStart(true); webapp.setContextPath("/"); - webapp.setExtractWAR(true); //false - webapp.setParentLoaderPriority(false); + webapp.setExtractWAR(true); + webapp.setParentLoaderPriority(false); //true); -// webappcontext.setWar("BKULocal-1.0.4-SNAPSHOT.war"); - webapp.setWar(getClass().getClassLoader().getResource("BKULocalWar/").toString()); - -// handlers.setHandlers(new Handler[] { webappcontext, new DefaultHandler() }); + webapp.setWar(copyWebapp(webapp.getTempDirectory())); //getClass().getClassLoader().getResource("BKULocalWar/").toString()); server.setHandler(webapp); server.setGracefulShutdown(1000*3); } + + private String copyWebapp(File webappDir) throws IOException { + File webapp = new File(webappDir, "BKULocal.war"); + log.debug("copying BKULocal classpath resource to " + webapp); + InputStream is = getClass().getClassLoader().getResourceAsStream("BKULocal.war"); + OutputStream os = new BufferedOutputStream(new FileOutputStream(webapp)); + StreamUtil.copyStream(is, os); + os.close(); + return webapp.getPath(); + } + public void start() throws Exception { server.start(); } diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java new file mode 100644 index 00000000..97ca716b --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java @@ -0,0 +1,138 @@ +package at.gv.egiz.bku.webstart; + +import iaik.asn1.CodingException; +import iaik.asn1.ObjectID; +import iaik.asn1.structures.AlgorithmID; +import iaik.asn1.structures.GeneralName; +import iaik.asn1.structures.GeneralNames; +import iaik.asn1.structures.Name; +import iaik.x509.X509Certificate; +import iaik.x509.extensions.AuthorityKeyIdentifier; +import iaik.x509.extensions.BasicConstraints; +import iaik.x509.extensions.ExtendedKeyUsage; +import iaik.x509.extensions.KeyUsage; + +import iaik.x509.extensions.SubjectAltName; +import iaik.x509.extensions.SubjectKeyIdentifier; +import java.io.IOException; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Random; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class TLSServerCA { + public static final int CA_VALIDITY_Y = 3; + public static final int SERVER_VALIDITY_Y = 3; + private final static Log log = LogFactory.getLog(TLSServerCA.class); + + private KeyPair caKeyPair; + private X509Certificate caCert; + + private KeyPair serverKeyPair; + private X509Certificate serverCert; + + private KeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); + gen.initialize(2048); + return gen.generateKeyPair(); + } + + private void generateCACert() throws GeneralSecurityException, CodingException { + log.debug("generating MOCCA CA certificate"); + Name subject = new Name(); + subject.addRDN(ObjectID.country, "AT"); + subject.addRDN(ObjectID.organization, "MOCCA"); + subject.addRDN(ObjectID.organizationalUnit, "MOCCA TLS Server CA"); + + caKeyPair = generateKeyPair(); + caCert = new X509Certificate(); + caCert.setSerialNumber(new BigInteger(20, new Random())); + caCert.setSubjectDN(subject); + caCert.setPublicKey(caKeyPair.getPublic()); + caCert.setIssuerDN(subject); + + caCert.addExtension(new SubjectKeyIdentifier(caKeyPair.getPublic())); + + caCert.addExtension(new BasicConstraints(true)); + caCert.addExtension(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign + | KeyUsage.digitalSignature)); + + GregorianCalendar date = new GregorianCalendar(); + date.add(Calendar.HOUR_OF_DAY, -1); + caCert.setValidNotBefore(date.getTime()); + date.add(Calendar.YEAR, CA_VALIDITY_Y); + caCert.setValidNotAfter(date.getTime()); + caCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); + + log.debug("successfully generated MOCCA TLS Server CA certificate " + caCert.getSubjectDN()); + } + + private void generateServerCert() throws GeneralSecurityException, CodingException { + log.debug("generating MOCCA server certificate"); + Name subject = new Name(); + subject.addRDN(ObjectID.country, "AT"); + subject.addRDN(ObjectID.organization, "MOCCA"); + subject.addRDN(ObjectID.organizationalUnit, "MOCCA TLS Server"); + subject.addRDN(ObjectID.commonName, "localhost"); + subject.addRDN(ObjectID.commonName, "127.0.0.1"); + + serverKeyPair = generateKeyPair(); + serverCert = new X509Certificate(); + serverCert.setSerialNumber(new BigInteger(20, new Random())); + serverCert.setSubjectDN(subject); + serverCert.setPublicKey(serverKeyPair.getPublic()); + serverCert.setIssuerDN(caCert.getSubjectDN()); + + serverCert.addExtension(new SubjectKeyIdentifier(serverKeyPair.getPublic())); + byte[] aki = new SubjectKeyIdentifier(caCert.getPublicKey()).get(); + serverCert.addExtension(new AuthorityKeyIdentifier(aki)); + + serverCert.addExtension(new ExtendedKeyUsage(ExtendedKeyUsage.serverAuth)); + + GeneralNames altNames = new GeneralNames(); + altNames.addName(new GeneralName(GeneralName.dNSName, "localhost")); + altNames.addName(new GeneralName(GeneralName.dNSName, "127.0.0.1")); + altNames.addName(new GeneralName(GeneralName.iPAddress, "127.0.0.1")); + serverCert.addExtension(new SubjectAltName(altNames)); + + serverCert.addExtension(new BasicConstraints(false)); + serverCert.addExtension(new KeyUsage(KeyUsage.keyEncipherment + | KeyUsage.digitalSignature)); + + GregorianCalendar date = new GregorianCalendar(); + date.add(Calendar.HOUR_OF_DAY, -1); + serverCert.setValidNotBefore(date.getTime()); + date.add(Calendar.YEAR,SERVER_VALIDITY_Y); + date.add(Calendar.HOUR_OF_DAY, -1); + serverCert.setValidNotAfter(date.getTime()); + serverCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); + + log.debug("successfully generated MOCCA TLS Server certificate " + serverCert.getSubjectDN()); + caKeyPair = null; + } + + public KeyStore generateKeyStore(char[] password) throws GeneralSecurityException, IOException, CodingException { +// try { + generateCACert(); + generateServerCert(); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + ks.setKeyEntry("server", serverKeyPair.getPrivate(), password, new X509Certificate[]{serverCert, caCert}); + return ks; +// } catch (Exception e) { +// log.error("Cannot generate certificate", e); +// } +// return null; + } + +} diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/ui/TrayIconDialog.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/ui/TrayIconDialog.java index 4679eac5..9990b2a0 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/ui/TrayIconDialog.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/ui/TrayIconDialog.java @@ -36,6 +36,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class TrayIconDialog implements TrayIconDialogInterface { + public static final String TRAYICON_RESOURCE = "at/gv/egiz/bku/webstart/ui/trayicon.png"; + public static final String TRAYMENU_SHUTDOWN = "TrayMenu.Shutdown"; + public static final String TRAYMENU_TOOLTIP = "TrayMenu.Tooltip"; private static Log log = LogFactory.getLog(TrayIconDialog.class); private static TrayIconDialogInterface instance; @@ -107,10 +110,10 @@ public class TrayIconDialog implements TrayIconDialogInterface { if (isSupported) { SystemTray tray = SystemTray.getSystemTray(); Image image = ImageIO.read(getClass().getClassLoader() - .getResourceAsStream("at/gv/egiz/bku/webstart/ui/logo.png")); + .getResourceAsStream(TRAYICON_RESOURCE)); PopupMenu popup = new PopupMenu(); MenuItem exitItem = new MenuItem(resourceBundel - .getString("TrayMenu.Shutdown")); + .getString(TRAYMENU_SHUTDOWN)); popup.add(exitItem); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -123,7 +126,7 @@ public class TrayIconDialog implements TrayIconDialogInterface { trayIcon = new TrayIcon(image, "BKULogo", popup); trayIcon.setImageAutoSize(true); - trayIcon.setToolTip(resourceBundel.getString("TrayMenu.Tooltip")); + trayIcon.setToolTip(resourceBundel.getString(TRAYMENU_TOOLTIP)); try { tray.add(trayIcon); } catch (AWTException e) { diff --git a/BKUWebStart/src/main/jnlp/resources/img/logo.png b/BKUWebStart/src/main/jnlp/resources/img/logo.png new file mode 100644 index 00000000..2c622d88 Binary files /dev/null and b/BKUWebStart/src/main/jnlp/resources/img/logo.png differ diff --git a/BKUWebStart/src/main/jnlp/resources/img/logo_64x64.png b/BKUWebStart/src/main/jnlp/resources/img/logo_64x64.png new file mode 100644 index 00000000..fa6d7f96 Binary files /dev/null and b/BKUWebStart/src/main/jnlp/resources/img/logo_64x64.png differ diff --git a/BKUWebStart/src/main/jnlp/resources/img/logo_90x90.png b/BKUWebStart/src/main/jnlp/resources/img/logo_90x90.png new file mode 100644 index 00000000..d7f8bbd0 Binary files /dev/null and b/BKUWebStart/src/main/jnlp/resources/img/logo_90x90.png differ diff --git a/BKUWebStart/src/main/jnlp/resources/img/splash.png b/BKUWebStart/src/main/jnlp/resources/img/splash.png new file mode 100644 index 00000000..72c1d868 Binary files /dev/null and b/BKUWebStart/src/main/jnlp/resources/img/splash.png differ diff --git a/BKUWebStart/src/main/jnlp/resources/img/version.xml b/BKUWebStart/src/main/jnlp/resources/img/version.xml new file mode 100644 index 00000000..715b6722 --- /dev/null +++ b/BKUWebStart/src/main/jnlp/resources/img/version.xml @@ -0,0 +1,17 @@ + + + + + logo.png + 1.0-SNAPSHOT + + logo.png + + + + splash.png + 1.0-SNAPSHOT + + splash.png + + diff --git a/BKUWebStart/src/main/jnlp/resources/logo.png b/BKUWebStart/src/main/jnlp/resources/logo.png deleted file mode 100644 index 2c622d88..00000000 Binary files a/BKUWebStart/src/main/jnlp/resources/logo.png and /dev/null differ diff --git a/BKUWebStart/src/main/jnlp/resources/logo_64x64.png b/BKUWebStart/src/main/jnlp/resources/logo_64x64.png deleted file mode 100644 index fa6d7f96..00000000 Binary files a/BKUWebStart/src/main/jnlp/resources/logo_64x64.png and /dev/null differ diff --git a/BKUWebStart/src/main/jnlp/resources/logo_90x90.png b/BKUWebStart/src/main/jnlp/resources/logo_90x90.png deleted file mode 100644 index d7f8bbd0..00000000 Binary files a/BKUWebStart/src/main/jnlp/resources/logo_90x90.png and /dev/null differ diff --git a/BKUWebStart/src/main/jnlp/resources/splash.png b/BKUWebStart/src/main/jnlp/resources/splash.png deleted file mode 100644 index 72c1d868..00000000 Binary files a/BKUWebStart/src/main/jnlp/resources/splash.png and /dev/null differ diff --git a/BKUWebStart/src/main/jnlp/resources/version.xml b/BKUWebStart/src/main/jnlp/resources/version.xml new file mode 100644 index 00000000..a5b10b47 --- /dev/null +++ b/BKUWebStart/src/main/jnlp/resources/version.xml @@ -0,0 +1,186 @@ + + + + + BKUWebStart-1.0.3-SNAPSHOT.jar + 1.0.3-SNAPSHOT + + BKUWebStart-1.0.3-SNAPSHOT.jar + + + + + commons-logging-1.0.4.jar + 1.0.4 + + commons-logging-1.0.4.jar + + + + + + activation-1.1.jar + 1.1 + + activation-1.1.jar + + + + + log4j-1.2.12.jar + 1.2.12 + + log4j-1.2.12.jar + + + + + iaik_ecc_signed-2.15.jar + 2.15 + + iaik_ecc_signed-2.15.jar + + + + iaik_jce_full_signed-3.16.jar + 3.16 + + iaik_jce_full_signed-3.16.jar + + + + iaik_xsect-1.14.jar + 1.14 + + iaik_xsect-1.14.jar + + + + + + jetty-6.1.15.jar + 6.1.15 + + jetty-6.1.15.jar + + + + jetty-util-6.1.15.jar + 6.1.15 + + jetty-util-6.1.15.jar + + + + servlet-api-2.5-20081211.jar + 2.5-20081211 + + servlet-api-2.5-20081211.jar + + + + + jaxb-api-2.1.jar + 2.1 + + jaxb-api-2.1.jar + + + + jaxb-impl-2.1.9.jar + 2.1.9 + + jaxb-impl-2.1.9.jar + + + + stax-api-1.0-2.jar + 1.0-2 + + stax-api-1.0-2.jar + + + + + + utils-1.1.2-SNAPSHOT.jar + 1.1.2-SNAPSHOT + + utils-1.1.2-SNAPSHOT.jar + + + + diff --git a/BKUWebStart/src/main/jnlp/template.xml b/BKUWebStart/src/main/jnlp/template.xml index 0a89a036..a355da77 100644 --- a/BKUWebStart/src/main/jnlp/template.xml +++ b/BKUWebStart/src/main/jnlp/template.xml @@ -1,15 +1,20 @@ - + + + $project.Name $project.Organization.Name $project.Description - - + $project.Description + + - + #if($offlineAllowed) diff --git a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/logo.png b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/logo.png deleted file mode 100644 index 598ab00b..00000000 Binary files a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/logo.png and /dev/null differ diff --git a/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/trayicon.png b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/trayicon.png new file mode 100644 index 00000000..2c622d88 Binary files /dev/null and b/BKUWebStart/src/main/resources/at/gv/egiz/bku/webstart/ui/trayicon.png differ diff --git a/BKUWebStart/src/main/resources/logo.png b/BKUWebStart/src/main/resources/logo.png deleted file mode 100644 index fa6d7f96..00000000 Binary files a/BKUWebStart/src/main/resources/logo.png and /dev/null differ diff --git a/BKUWebStart/src/main/resources/splash.png b/BKUWebStart/src/main/resources/splash.png deleted file mode 100644 index 72c1d868..00000000 Binary files a/BKUWebStart/src/main/resources/splash.png and /dev/null differ -- cgit v1.2.3