diff options
| author | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-06-12 12:42:05 +0000 | 
|---|---|---|
| committer | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-06-12 12:42:05 +0000 | 
| commit | 61366ba8efcc0cf3d36438e9ee26228e7bc66174 (patch) | |
| tree | 707016a32d57ab734396b24675659a92f2317278 /BKUWebStart/src/main/java | |
| parent | 0d5e54423b3cbc6c16b28800890c6ee5a5aacf75 (diff) | |
| download | mocca-61366ba8efcc0cf3d36438e9ee26228e7bc66174.tar.gz mocca-61366ba8efcc0cf3d36438e9ee26228e7bc66174.tar.bz2 mocca-61366ba8efcc0cf3d36438e9ee26228e7bc66174.zip | |
BKU Web Start 
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@361 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'BKUWebStart/src/main/java')
| -rw-r--r-- | BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java | 339 | ||||
| -rw-r--r-- | BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java | 60 | ||||
| -rw-r--r-- | BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java (renamed from BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java) | 75 | ||||
| -rw-r--r-- | BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/ui/TrayIconDialog.java | 9 | 
4 files changed, 338 insertions, 145 deletions
| 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/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/CA.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java index f81d3d83..97ca716b 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/CA.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java @@ -1,12 +1,20 @@  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;
 @@ -22,8 +30,10 @@ 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);
 +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;
 @@ -31,21 +41,18 @@ public class CA {    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");
 +  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-CA");
 +    subject.addRDN(ObjectID.organizationalUnit, "MOCCA TLS Server CA");
      caKeyPair = generateKeyPair();
      caCert = new X509Certificate();
 @@ -54,6 +61,8 @@ public class CA {      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));
 @@ -61,23 +70,22 @@ public class CA {      GregorianCalendar date = new GregorianCalendar();
      date.add(Calendar.HOUR_OF_DAY, -1);
      caCert.setValidNotBefore(date.getTime());
 -    date.add(Calendar.YEAR, 7);
 +    date.add(Calendar.YEAR, CA_VALIDITY_Y);
      caCert.setValidNotAfter(date.getTime());
      caCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate());
 -    log.debug("Successfully signed CA certificate");
 +    
 +    log.debug("successfully generated MOCCA TLS Server CA certificate " + caCert.getSubjectDN());
    }
 -  private void generateServerCert() throws GeneralSecurityException {
 -    log.debug("Generating SSL certificate");
 +  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");
 -    try {
 -      subject.addRDN(ObjectID.commonName, InetAddress.getLocalHost()
 -          .getHostName());
 -    } catch (UnknownHostException e) {
 -      subject.addRDN(ObjectID.commonName, "localhost");
 -    }
 +    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()));
 @@ -85,6 +93,18 @@ public class CA {      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));
 @@ -92,26 +112,27 @@ public class CA {      GregorianCalendar date = new GregorianCalendar();
      date.add(Calendar.HOUR_OF_DAY, -1);
      serverCert.setValidNotBefore(date.getTime());
 -    date.add(Calendar.YEAR, 7);
 +    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 signed server certificate");
 +
 +    log.debug("successfully generated MOCCA TLS Server certificate " + serverCert.getSubjectDN());
      caKeyPair = null;
    }
 -  public KeyStore generateKeyStore(char[] password) {
 -    try {
 -      generateCA();
 +  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;
 +//    } 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) { | 
