diff options
Diffstat (limited to 'BKUWebStart/src/main/java/at/gv/egiz/bku')
6 files changed, 1151 insertions, 432 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 deleted file mode 100644 index abc0b8ee..00000000 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/BKULauncher.java +++ /dev/null @@ -1,418 +0,0 @@ -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;
-
-//import org.apache.commons.cli.CommandLine;
-//import org.apache.commons.cli.CommandLineParser;
-//import org.apache.commons.cli.HelpFormatter;
-//import org.apache.commons.cli.Options;
-//import org.apache.commons.cli.ParseException;
-//import org.apache.commons.cli.PosixParser;
-import org.apache.commons.logging.Log;
-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.BindException;
-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;
-import org.mortbay.util.MultiException;
-
-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 = "configuration.zip";
- public static final String CONF_TEMPLATE_RESOURCE = "at/gv/egiz/bku/webstart/conf/configuration.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 STARTUP_CAPTION = "Startup.Caption";
- public static final String ERROR_CAPTION = "Error.Caption";
- public static final String STARTUP_MESSAGE = "Startup.Message";
- public static final String ERROR_STARTUP_MESSAGE = "Error.Startup.Message";
- public static final String ERROR_CONF_MESSAGE = "Error.Conf.Message";
- public static final String ERROR_BIND_MESSAGE = "Error.Bind.Message";
- public static final String VERSION_FILE = ".version";
- private static Log log = LogFactory.getLog(BKULauncher.class);
- private ResourceBundle resourceBundle = null;
- private Container server;
-
- 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) {
- log.debug("comparing " + oldVersion + " to " + MIN_CONFIG_VERSION);
-
- int majorEnd = oldVersion.indexOf('-');
- String oldMajor = (majorEnd < 0) ? oldVersion : oldVersion.substring(0, majorEnd);
-
- int compare = oldMajor.compareTo(MIN_CONFIG_VERSION);
- if (compare < 0 ||
- // SNAPSHOT versions are pre-releases (update if release required)
- (compare == 0 && oldVersion.startsWith("-SNAPSHOT", majorEnd))) {
- return true;
- } else {
- return false;
- }
- }
- 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"));
- // xcfg.configure(server);
- server.init();
- server.start();
- }
-
- private void initTrayIcon() {
- log.debug("init MOCCA tray icon");
- Locale loc = Locale.getDefault();
- try {
- resourceBundle = ResourceBundle.getBundle(
- MESSAGES_RESOURCE, loc);
- } catch (MissingResourceException mx) {
- resourceBundle = ResourceBundle.getBundle(
- MESSAGES_RESOURCE, Locale.ENGLISH);
- }
- TrayIconDialog.getInstance().init(resourceBundle);
- TrayIconDialog.getInstance().setShutdownHook(this);
-// TrayIconDialog.getInstance().displayInfo(GREETING_CAPTION, GREETING_MESSAGE);
- }
-
- private void initStart() {
- }
-
- private void initFinished(boolean installCert) {
- try {
-// if (splash != null) {
-// try {
-// splash.close();
-// } catch (IllegalStateException ex) {
-// log.warn("Failed to close splash screen: " + ex.getMessage());
-// }
-// }
-
- if (installCert) {
- log.debug("trying install MOCCA certificate on system browser");
- 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.warn("failed to join MOCCA server: " + e.getMessage(), e);
- }
- }
-
- private void unzip(File zipfile) throws IOException {
- File dir = zipfile.getParentFile();
- ZipFile zipFile = new ZipFile(zipfile);
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry entry = entries.nextElement();
- File eF = new File(dir, entry.getName());
- if (entry.isDirectory()) {
- eF.mkdirs();
- continue;
- }
- File f = new File(eF.getParent());
- f.mkdirs();
- StreamUtil.copyStream(zipFile.getInputStream(entry),
- new FileOutputStream(eF));
- }
- zipFile.close();
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) throws InterruptedException {
-
- if (log.isDebugEnabled()) {
- //System.setProperty("DEBUG", "true");
- System.setProperty("VERBOSE", "true");
- System.setProperty("javax.net.debug", "ssl,handshake");
- }
-
-// log.warn("***** DISABLING SECURITY MANAGER *******");
- System.setSecurityManager(null);
-
- BKULauncher launcher = new BKULauncher();
- launcher.initStart();
-
- boolean installCert = false;
-
- launcher.initTrayIcon();
- TrayIconDialog.getInstance().displayInfo(STARTUP_CAPTION, STARTUP_MESSAGE);
-
- try {
- File configDir = new File(System.getProperty("user.home") + '/' + CONFIG_DIR);
- installCert = launcher.ensureConfig(configDir);
- } catch (Exception ex) {
- log.fatal("Failed to init MOCCA configuration, exiting", ex);
- TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_CONF_MESSAGE);
- Thread.sleep(5000);
- System.exit(-1000);
- }
-
- try {
- launcher.startUpServer();
- TrayIconDialog.getInstance().displayInfo(GREETING_CAPTION, GREETING_MESSAGE);
- launcher.initFinished(installCert);
- } catch (BindException ex) {
- log.fatal("Failed to launch MOCCA, " + ex.getMessage(), ex);
- TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_BIND_MESSAGE);
- Thread.sleep(5000);
- System.exit(-1000);
- } catch (MultiException ex) {
- log.fatal("Failed to launch MOCCA, " + ex.getMessage(), ex);
- if (ex.getThrowable(0) instanceof BindException) {
- TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_BIND_MESSAGE);
- } else {
- TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_STARTUP_MESSAGE);
- }
- Thread.sleep(5000);
- System.exit(-1000);
- } catch (Exception e) {
- log.fatal("Failed to launch MOCCA, " + e.getMessage(), e);
- TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_STARTUP_MESSAGE);
- Thread.sleep(5000);
- 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() {
- log.info("Shutting down server");
- if ((server != null) && (server.isRunning())) {
- try {
- if (server.isRunning()) {
- server.stop();
- }
- } catch (Exception e) {
- log.debug(e.toString());
- } finally {
- if (server.isRunning()) {
- server.destroy();
- }
- }
- }
- System.exit(0);
- }
-}
diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java new file mode 100644 index 00000000..ab1746ed --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java @@ -0,0 +1,418 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.webstart; + +import at.gv.egiz.bku.utils.StreamUtil; +import iaik.asn1.CodingException; +import iaik.xml.crypto.utils.Utils; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.jdt.core.dom.ThisExpression; + +/** + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class Configurator { + + /** + * MOCCA configuration + * configurations with less than this (major) version will be backuped and updated + * allowed: MAJOR[.MINOR[.X[-SNAPSHOT]]] + */ + public static final String MIN_CONFIG_VERSION = "1.0.9-SNAPSHOT"; + public static final String CONFIG_DIR = ".mocca/conf/"; + public static final String CERTS_DIR = ".mocca/certs/"; + public static final String VERSION_FILE = ".version"; + public static final String UNKOWN_VERSION = "unknown"; + public static final String CONF_TEMPLATE_FILE = "conf-tmp.zip"; + public static final String CONF_TEMPLATE_RESOURCE = "at/gv/egiz/bku/webstart/conf/conf.zip"; + public static final String CERTIFICATES_PKG = "at/gv/egiz/bku/certs"; + + /** + * MOCCA TLS certificate + */ + public static final String KEYSTORE_FILE = "keystore.ks"; + public static final String PASSWD_FILE = ".secret"; + + private static final Log log = LogFactory.getLog(Configurator.class); + + /** currently installed configuration version */ + private String version; + private String certsVersion; + /** whether a new MOCCA TLS cert was created during initialization */ + private boolean certRenewed = false; + + /** + * Checks whether the config directory already exists and creates it otherwise. + * @param configDir the config directory to be created + * @throws IOException config/certificate creation failed + * @throws GeneralSecurityException if MOCCA TLS certificate could not be created + * @throws CodingException if MOCCA TLS certificate could not be created + */ + public void ensureConfiguration() throws IOException, CodingException, GeneralSecurityException { + File configDir = new File(System.getProperty("user.home") + '/' + CONFIG_DIR); + if (configDir.exists()) { + if (configDir.isFile()) { + log.error("invalid config directory: " + configDir); + throw new IOException("invalid config directory: " + configDir); + } else { + version = readVersion(new File(configDir, VERSION_FILE)); + if (log.isDebugEnabled()) { + log.debug("config directory " + configDir + ", version " + version); + } + if (updateRequired(version)) { + File moccaDir = configDir.getParentFile(); + File zipFile = new File(moccaDir, "conf-" + version + ".zip"); + ZipOutputStream zipOS = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + log.info("backup configuration to " + zipFile); + backupAndDelete(configDir, moccaDir.toURI(), zipOS); + zipOS.close(); + initConfig(configDir); + } + } + } else { + initConfig(configDir); + } + } + + /** + * To be replaced by TSLs in IAIK-PKI + * @throws IOException + */ + public void ensureCertificates() throws IOException { + File certsDir = new File(System.getProperty("user.home") + '/' + CERTS_DIR); + if (certsDir.exists()) { + if (certsDir.isFile()) { + log.error("invalid certificate store directory: " + certsDir); + throw new IOException("invalid config directory: " + certsDir); + } else { + certsVersion = readVersion(new File(certsDir, VERSION_FILE)); + if (log.isDebugEnabled()) { + log.debug("certificate-store directory " + certsDir + ", version " + certsVersion); + } + String newCertsVersion = getCertificatesVersion(); + if (updateRequiredStrict(certsVersion, newCertsVersion)) { + File moccaDir = certsDir.getParentFile(); + File zipFile = new File(moccaDir, "certs-" + certsVersion + ".zip"); + ZipOutputStream zipOS = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + log.info("backup certificates to " + zipFile); + backupAndDelete(certsDir, moccaDir.toURI(), zipOS); + zipOS.close(); + + createCerts(certsDir, newCertsVersion); + certsVersion = newCertsVersion; + } + } + } else { + String newCertsVersion = getCertificatesVersion(); + createCerts(certsDir, newCertsVersion); + certsVersion = newCertsVersion; + } + } + + /** + * + * @return whether a new MOCCA TLS certificate has been created during initialization + */ + public boolean isCertRenewed() { + return certRenewed; + } + + /** + * @return The first valid (not empty, no comment) line of the version file or + * "unknown" if version file cannot be read or does not contain such a line. + */ + protected static String readVersion(File versionFile) { + if (versionFile.exists() && versionFile.canRead()) { + BufferedReader versionReader = null; + try { + versionReader = new BufferedReader(new FileReader(versionFile)); + String version; + while ((version = versionReader.readLine().trim()) != null) { + if (version.length() > 0 && !version.startsWith("#")) { + log.debug("configuration version from " + versionFile + ": " + version); + return version; + } + } + } catch (IOException ex) { + log.error("failed to read configuration version from " + versionFile, ex); + } finally { + try { + versionReader.close(); + } catch (IOException ex) { + } + } + } + log.debug("unknown configuration version"); + return UNKOWN_VERSION; + } + + /** + * Temporary workaround, replace with TSLs in IAIK-PKI. + * Retrieves version from BKUCertificates.jar Manifest file. + * The (remote) resource URL will be handled by the JNLP loader, + * and the resource retrieved from the cache. + * + * @return + * @throws IOException + */ + private static String getCertificatesVersion() throws IOException { + String certsResourceVersion = null; + URL certsURL = Configurator.class.getClassLoader().getResource(CERTIFICATES_PKG); + if (certsURL != null) { + StringBuilder url = new StringBuilder(certsURL.toExternalForm()); + url = url.replace(url.length() - CERTIFICATES_PKG.length(), url.length(), "META-INF/MANIFEST.MF"); + log.trace("retrieve certificates resource version from " + url); + certsURL = new URL(url.toString()); + Manifest certsManifest = new Manifest(certsURL.openStream()); + Attributes atts = certsManifest.getMainAttributes(); + if (atts != null) { + certsResourceVersion = atts.getValue("Implementation-Version"); + log.debug("certs resource version: " + certsResourceVersion); + } + } else { + log.error("Failed to retrieve certificates resource " + CERTIFICATES_PKG); + throw new IOException("Failed to retrieve certificates resource " + CERTIFICATES_PKG); + } + return certsResourceVersion; + } + + protected static boolean updateRequired(String oldVersion) { + log.debug("comparing " + oldVersion + " to " + MIN_CONFIG_VERSION); + if (oldVersion != null && !UNKOWN_VERSION.equals(oldVersion)) { + + int majorEnd = oldVersion.indexOf('-'); + String oldMajor = (majorEnd < 0) ? oldVersion : oldVersion.substring(0, majorEnd); + + String minMajor = MIN_CONFIG_VERSION; + boolean releaseRequired = true; + if (MIN_CONFIG_VERSION.endsWith("-SNAPSHOT")) { + releaseRequired = false; + minMajor = minMajor.substring(0, minMajor.length() - 9); + } + + int compare = oldMajor.compareTo(minMajor); + if (compare < 0 || + // SNAPSHOT versions are pre-releases (update if release required) + (compare == 0 && releaseRequired && oldVersion.startsWith("-SNAPSHOT", majorEnd))) { + log.debug("configuration update required"); + return true; + } else { + log.debug("configuration up to date"); + return false; + } + } + log.debug("no old version, configuration update required"); + return true; + } + + /** + * if unknown old, update in any case + * if known old and unknown new, don't update + * @param oldVersion + * @param newVersion + * @return + */ + private boolean updateRequiredStrict(String oldVersion, String newVersion) { + log.debug("comparing " + oldVersion + " to " + newVersion); + if (oldVersion != null && !UNKOWN_VERSION.equals(oldVersion)) { + if (newVersion != null && !UNKOWN_VERSION.equals(newVersion)) { + String[] oldV = oldVersion.split("-"); + String[] newV = newVersion.split("-"); + log.trace("comparing " + oldV[0] + " to " + newV[0]); + if (oldV[0].compareTo(newV[0]) < 0) { + log.debug("update required"); + return true; + } else { + log.trace("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; + } + } + } + log.debug("unknown new version, do not update"); + return true; + } + log.debug("unknown old version, update required"); + return true; + } + + protected static 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(); + } + } + + /** + * set up a new MOCCA local configuration + * (not to be called directly, call ensureConfiguration()) + * @throws IOException config/certificate creation failed + * @throws GeneralSecurityException if MOCCA TLS certificate could not be created + * @throws CodingException if MOCCA TLS certificate could not be created + */ + protected void initConfig(File configDir) throws IOException, GeneralSecurityException, CodingException { + createConfig(configDir, Launcher.version); + version = Launcher.version; + createKeyStore(configDir); + certRenewed = true; + } + + private static void createConfig(File configDir, String version) throws IOException { + if (log.isDebugEnabled()) { + log.debug("creating configuration version " + Launcher.version + " in " + configDir ); + } + configDir.mkdirs(); + File confTemplateFile = new File(configDir, CONF_TEMPLATE_FILE); + InputStream is = Configurator.class.getClassLoader().getResourceAsStream(CONF_TEMPLATE_RESOURCE); + OutputStream os = new BufferedOutputStream(new FileOutputStream(confTemplateFile)); + StreamUtil.copyStream(is, os); + os.close(); + unzip(confTemplateFile, configDir); + confTemplateFile.delete(); + writeVersionFile(new File(configDir, VERSION_FILE), version); + } + + /** + * set up a new MOCCA local certStore + * @throws IOException config/certificate creation failed + * @throws GeneralSecurityException if MOCCA TLS certificate could not be created + * @throws CodingException if MOCCA TLS certificate could not be created + */ + private static void createCerts(File certsDir, String certsVersion) throws IOException { + if (log.isDebugEnabled()) { + log.debug("creating certificate-store " + certsDir + ", version " + certsVersion); + } + URL certsURL = Configurator.class.getClassLoader().getResource(CERTIFICATES_PKG); + if (certsURL != null) { + StringBuilder url = new StringBuilder(certsURL.toExternalForm()); + url = url.replace(url.length() - CERTIFICATES_PKG.length(), url.length(), "META-INF/MANIFEST.MF"); + log.debug("retrieve certificate resource names from " + url); + certsURL = new URL(url.toString()); + Manifest certsManifest = new Manifest(certsURL.openStream()); + certsDir.mkdirs(); + Iterator<String> entries = certsManifest.getEntries().keySet().iterator(); + while (entries.hasNext()) { + String entry = entries.next(); + if (entry.startsWith(CERTIFICATES_PKG)) { + String f = entry.substring(CERTIFICATES_PKG.length()); // "/trustStore/..." + new File(certsDir, f.substring(0, f.lastIndexOf('/'))).mkdirs(); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(certsDir, f))); + log.debug(f); + StreamUtil.copyStream(Configurator.class.getClassLoader().getResourceAsStream(entry), bos); + bos.close(); + } else { + log.trace("ignore " + entry); + } + } + writeVersionFile(new File(certsDir, VERSION_FILE), certsVersion); + } else { + log.error("Failed to retrieve certificates resource " + CERTIFICATES_PKG); + throw new IOException("Failed to retrieve certificates resource " + CERTIFICATES_PKG); + } + } + + private static void unzip(File zipfile, File toDir) throws IOException { + ZipFile zipFile = new ZipFile(zipfile); + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + File eF = new File(toDir, entry.getName()); + if (entry.isDirectory()) { + eF.mkdirs(); + continue; + } + File f = new File(eF.getParent()); + f.mkdirs(); + StreamUtil.copyStream(zipFile.getInputStream(entry), + new FileOutputStream(eF)); + } + zipFile.close(); + } + + private static 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 static void createKeyStore(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(false, false) || !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); + File ksFile = new File(configDir, KEYSTORE_FILE); + FileOutputStream fos = new FileOutputStream(ksFile); + ks.store(fos, password); + fos.close(); + } +} 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 89044486..4df90ab2 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,22 +1,28 @@ package at.gv.egiz.bku.webstart;
import at.gv.egiz.bku.utils.StreamUtil;
+import java.awt.AWTPermission;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FilePermission;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.ReflectPermission;
+import java.net.NetPermission;
+import java.net.SocketPermission;
+import java.security.Permissions;
+import java.security.SecurityPermission;
+import java.util.PropertyPermission;
+import javax.smartcardio.CardPermission;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
-import org.mortbay.jetty.handler.DefaultHandler;
-import org.mortbay.jetty.handler.HandlerCollection;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
@@ -28,12 +34,18 @@ public class Container { public static final String HTTPS_PORT_PROPERTY = "mocca.http.port";
private static Log log = LogFactory.getLog(Container.class);
+ static {
+ if (log.isDebugEnabled()) {
+ //Jetty log INFO and WARN, include ignored exceptions
+ //jetty logging may be further restricted by setting level in log4j.properties
+ System.setProperty("VERBOSE", "true");
+ //do not set Jetty DEBUG logging, produces loads of output
+ //System.setProperty("DEBUG", "true");
+ }
+ }
private Server server;
- public Container() {
- }
-
public void init() throws IOException {
// System.setProperty("DEBUG", "true");
server = new Server();
@@ -55,15 +67,15 @@ public class Container { sslConnector.setPort(Integer.getInteger(HTTPS_PORT_PROPERTY, 3496).intValue());
sslConnector.setAcceptors(1);
sslConnector.setHost("127.0.0.1");
- File configDir = new File(System.getProperty("user.home") + "/" + BKULauncher.CONFIG_DIR);
- File keystoreFile = new File(configDir, BKULauncher.KEYSTORE_FILE);
+ File configDir = new File(System.getProperty("user.home") + "/" + Configurator.CONFIG_DIR);
+ File keystoreFile = new File(configDir, Configurator.KEYSTORE_FILE);
if (!keystoreFile.canRead()) {
log.error("MOCCA keystore file not readable: " + keystoreFile.getAbsolutePath());
throw new FileNotFoundException("MOCCA keystore file not readable: " + keystoreFile.getAbsolutePath());
}
log.debug("loading MOCCA keystore from " + keystoreFile.getAbsolutePath());
sslConnector.setKeystore(keystoreFile.getAbsolutePath());
- File passwdFile = new File(configDir, BKULauncher.PASSWD_FILE);
+ File passwdFile = new File(configDir, Configurator.PASSWD_FILE);
BufferedReader reader = new BufferedReader(new FileReader(passwdFile));
String pwd;
while ((pwd = reader.readLine()) != null) {
@@ -107,7 +119,6 @@ public class Container { sslConnector.setExcludeCipherSuites(RFC4492CipherSuites);
-
server.setConnectors(new Connector[] { connector, sslConnector });
WebAppContext webapp = new WebAppContext();
@@ -116,13 +127,13 @@ public class Container { webapp.setExtractWAR(true);
webapp.setParentLoaderPriority(false);
- webapp.setWar(copyWebapp(webapp.getTempDirectory())); //getClass().getClassLoader().getResource("BKULocalWar/").toString());
-
+ webapp.setWar(copyWebapp(webapp.getTempDirectory()));
+ webapp.setPermissions(getPermissions(webapp.getTempDirectory()));
+
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);
@@ -133,6 +144,44 @@ public class Container { return webapp.getPath();
}
+ private Permissions getPermissions(File webappDir) {
+ Permissions perms = new Permissions();
+
+ // jetty-webstart (spring?)
+ perms.add(new RuntimePermission("getClassLoader"));
+
+ // standard permissions
+ perms.add(new PropertyPermission("*", "read"));
+ perms.add(new RuntimePermission("accessDeclaredMembers"));
+ perms.add(new RuntimePermission("accessClassInPackage.*"));
+ perms.add(new RuntimePermission("defineClassInPackage.*"));
+ perms.add(new RuntimePermission("setFactory"));
+ perms.add(new RuntimePermission("getProtectionDomain"));
+ perms.add(new RuntimePermission("modifyThread"));
+ perms.add(new RuntimePermission("modifyThreadGroup"));
+ perms.add(new RuntimePermission("setFactory"));
+ perms.add(new ReflectPermission("suppressAccessChecks"));
+
+ // MOCCA specific
+ perms.add(new SocketPermission("*", "connect,resolve"));
+ perms.add(new NetPermission("specifyStreamHandler"));
+ perms.add(new SecurityPermission("insertProvider.*"));
+ perms.add(new SecurityPermission("putProviderProperty.*"));
+ perms.add(new SecurityPermission("removeProvider.*"));
+ perms.add(new CardPermission("*", "*"));
+ perms.add(new AWTPermission("*"));
+
+ perms.add(new FilePermission(webappDir.getAbsolutePath() + "/-", "read"));
+ perms.add(new FilePermission(new File(System.getProperty("java.home") + "/lib/xalan.properties").getAbsolutePath(), "read"));
+ perms.add(new FilePermission(new File(System.getProperty("java.home") + "/lib/xerces.properties").getAbsolutePath(), "read"));
+ perms.add(new FilePermission(new File(System.getProperty("user.home")).getAbsolutePath(), "read, write"));
+ perms.add(new FilePermission(new File(System.getProperty("user.home") + "/-").getAbsolutePath(), "read, write"));
+ perms.add(new FilePermission(new File(System.getProperty("user.home") + "/.mocca/logs/*").getAbsolutePath(), "read, write,delete"));
+
+
+ return perms;
+ }
+
public void start() throws Exception {
server.start();
}
diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java new file mode 100644 index 00000000..f7be7b65 --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java @@ -0,0 +1,230 @@ +package at.gv.egiz.bku.webstart;
+
+import iaik.asn1.CodingException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.jnlp.UnavailableServiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.webstart.ui.BKUControllerInterface;
+import at.gv.egiz.bku.webstart.ui.TrayIconDialog;
+import com.sun.javaws.security.JavaWebStartSecurity;
+import java.awt.Desktop;
+import java.awt.SplashScreen;
+import java.net.BindException;
+import java.net.URI;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import javax.jnlp.BasicService;
+import javax.jnlp.ServiceManager;
+import org.mortbay.util.MultiException;
+
+public class Launcher implements BKUControllerInterface {
+
+ public static final String WEBAPP_RESOURCE = "BKULocal.war";
+ public static final String CERTIFICATES_RESOURCE = "BKUCertificates.jar";
+ public static final String WEBAPP_FILE = "BKULocal.war";
+ public static final String MESSAGES_RESOURCE = "at/gv/egiz/bku/webstart/ui/UIMessages";
+ /** resource bundle messages */
+ public static final String GREETING_CAPTION = "Greetings.Caption";
+ public static final String GREETING_MESSAGE = "Greetings.Message";
+ public static final String CONFIG_CAPTION = "Config.Caption";
+ public static final String CONFIG_MESSAGE = "Config.Message";
+ public static final String STARTUP_CAPTION = "Startup.Caption";
+ public static final String STARTUP_MESSAGE = "Startup.Message";
+ public static final String ERROR_CAPTION = "Error.Caption";
+ public static final String ERROR_STARTUP_MESSAGE = "Error.Startup.Message";
+ public static final String ERROR_CONF_MESSAGE = "Error.Conf.Message";
+ public static final String ERROR_BIND_MESSAGE = "Error.Bind.Message";
+ public static final URI HTTPS_SECURITY_LAYER_URI;
+ private static Log log = LogFactory.getLog(Launcher.class);
+
+ static {
+ URI tmp = null;
+ try {
+ tmp = new URI("https://localhost:" + Integer.getInteger(Container.HTTPS_PORT_PROPERTY, 3496).intValue());
+ } catch (URISyntaxException ex) {
+ log.error(ex);
+ } finally {
+ HTTPS_SECURITY_LAYER_URI = tmp;
+ }
+ }
+
+ public static final String version;
+ static {
+ String tmp = Configurator.UNKOWN_VERSION;
+ try {
+ String bkuWebStartJar = Launcher.class.getProtectionDomain().getCodeSource().getLocation().toString();
+ URL manifestURL = new URL("jar:" + bkuWebStartJar + "!/META-INF/MANIFEST.MF");
+ if (log.isTraceEnabled()) {
+ log.trace("read version information from " + manifestURL);
+ }
+ Manifest manifest = new Manifest(manifestURL.openStream());
+ Attributes atts = manifest.getMainAttributes();
+ if (atts != null) {
+ tmp = atts.getValue("Implementation-Build");
+ }
+ } catch (IOException ex) {
+ log.error("failed to read version", ex);
+ } finally {
+ version = tmp;
+ log.info("BKU Web Start " + version);
+ }
+ }
+
+ private Configurator config;
+ private Container server;
+ private BasicService basicService;
+
+ private void initStart() {
+ try {
+ basicService = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
+ if (basicService.isOffline()) {
+ log.info("launching MOCCA Web Start offline");
+ } else {
+ log.info("launching MOCCA Web Start online");
+ }
+ } catch (UnavailableServiceException ex) {
+ log.info("Failed to obtain JNLP service: " + ex.getMessage());
+ }
+ }
+
+ private void initTrayIcon() {
+ log.debug("init MOCCA tray icon");
+ Locale loc = Locale.getDefault();
+ ResourceBundle resourceBundle;
+ try {
+ resourceBundle = ResourceBundle.getBundle(
+ MESSAGES_RESOURCE, loc);
+ } catch (MissingResourceException mx) {
+ resourceBundle = ResourceBundle.getBundle(
+ MESSAGES_RESOURCE, Locale.ENGLISH);
+ }
+ TrayIconDialog.getInstance().init(resourceBundle);
+ TrayIconDialog.getInstance().setShutdownHook(this);
+// TrayIconDialog.getInstance().displayInfo(GREETING_CAPTION, GREETING_MESSAGE);
+ }
+
+ private void initConfig() throws IOException, CodingException, GeneralSecurityException {
+ config = new Configurator();
+ config.ensureConfiguration();
+ config.ensureCertificates();
+ }
+
+ private void startServer() throws Exception {
+ log.info("init servlet container and MOCCA webapp");
+ server = new Container();
+ server.init();
+ server.start();
+ }
+
+ private void initFinished() {
+ try {
+ // standalone (non-webstart) version has splashscreen
+ if (SplashScreen.getSplashScreen() != null) {
+ try {
+ SplashScreen.getSplashScreen().close();
+ } catch (IllegalStateException ex) {
+ log.warn("Failed to close splash screen: " + ex.getMessage());
+ }
+ }
+ if (config.isCertRenewed()) {
+ // don't use basicService.showDocument(), which causes a java ssl warning dialog
+ if (Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ if (desktop.isSupported(Desktop.Action.BROWSE)) {
+ try {
+ desktop.browse(HTTPS_SECURITY_LAYER_URI);
+ } catch (Exception ex) {
+ log.error("failed to open system browser, install TLS certificate manually: " + HTTPS_SECURITY_LAYER_URI, ex);
+ }
+ } else {
+ log.error("failed to open system browser, install TLS certificate manually: " + HTTPS_SECURITY_LAYER_URI);
+ }
+ } else {
+ log.error("failed to open system browser, install TLS certificate manually: " + HTTPS_SECURITY_LAYER_URI);
+ }
+ }
+ log.info("BKU successfully started");
+ server.join();
+ } catch (InterruptedException e) {
+ log.warn("failed to join server: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void shutDown() {
+ log.info("Shutting down server");
+ if ((server != null) && (server.isRunning())) {
+ try {
+ if (server.isRunning()) {
+ server.stop();
+ }
+ } catch (Exception e) {
+ log.debug(e.toString());
+ } finally {
+ if (server.isRunning()) {
+ server.destroy();
+ }
+ }
+ }
+ System.exit(0);
+ }
+
+ public static void main(String[] args) throws InterruptedException, IOException {
+
+ if (log.isTraceEnabled()) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm instanceof JavaWebStartSecurity) {
+ System.setSecurityManager(new LogSecurityManager((JavaWebStartSecurity) sm));
+ }
+ }
+
+ Launcher launcher = new Launcher();
+ launcher.initStart();
+ launcher.initTrayIcon(); //keep reference? BKULauncher not garbage collected after main()
+
+ try {
+ TrayIconDialog.getInstance().displayInfo(CONFIG_CAPTION, CONFIG_MESSAGE);
+ launcher.initConfig();
+ } catch (Exception ex) {
+ log.fatal("Failed to initialize configuration", ex);
+ TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_CONF_MESSAGE);
+ Thread.sleep(5000);
+ System.exit(-1000);
+ }
+
+ try {
+ TrayIconDialog.getInstance().displayInfo(STARTUP_CAPTION, STARTUP_MESSAGE);
+ launcher.startServer();
+ TrayIconDialog.getInstance().displayInfo(GREETING_CAPTION, GREETING_MESSAGE);
+ launcher.initFinished();
+ } catch (BindException ex) {
+ log.fatal("Failed to launch server, " + ex.getMessage(), ex);
+ TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_BIND_MESSAGE);
+ Thread.sleep(5000);
+ System.exit(-1000);
+ } catch (MultiException ex) {
+ log.fatal("Failed to launch server, " + ex.getMessage(), ex);
+ if (ex.getThrowable(0) instanceof BindException) {
+ TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_BIND_MESSAGE);
+ } else {
+ TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_STARTUP_MESSAGE);
+ }
+ Thread.sleep(5000);
+ System.exit(-1000);
+ } catch (Exception e) {
+ log.fatal("Failed to launch server, " + e.getMessage(), e);
+ TrayIconDialog.getInstance().displayError(ERROR_CAPTION, ERROR_STARTUP_MESSAGE);
+ Thread.sleep(5000);
+ System.exit(-1000);
+ }
+ }
+}
diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java new file mode 100644 index 00000000..99fd403b --- /dev/null +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java @@ -0,0 +1,440 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.webstart; + +import com.sun.javaws.security.JavaWebStartSecurity; +import java.io.FileDescriptor; +import java.net.InetAddress; +import java.security.Permission; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * JVM argument -Djava.security.debug=access,failure + * (passed as attribute to java element in jnlp) is ignored. + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class LogSecurityManager extends SecurityManager { + + protected static final Log log = LogFactory.getLog(LogSecurityManager.class); + JavaWebStartSecurity sm; + + public LogSecurityManager(JavaWebStartSecurity sm) { + this.sm = sm; +// AppPolicy policy = AppPolicy.getInstance(); +// SecurityManager sm = System.getSecurityManager(); + } + + @Override + public void checkAccept(String host, int port) { + try { + sm.checkAccept(host, port); + } catch (SecurityException ex) { + log.warn("checkAccept(" + host + ", " + port + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkAccess(Thread g) { + try { + sm.checkAccess(g); + } catch (SecurityException ex) { + log.warn("checkAccess(" + g + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkAccess(ThreadGroup g) { + try { + sm.checkAccess(g); + } catch (SecurityException ex) { + log.warn("checkAccess(" + g + "): " + ex.getMessage(), ex); + throw ex; + } + + } + + @Override + public void checkAwtEventQueueAccess() { + try { + sm.checkAwtEventQueueAccess(); + } catch (SecurityException ex) { + log.warn("checkAwtEventQAccess():" + ex.getMessage(), ex); + throw ex; + } + + } + + @Override + public void checkConnect(String host, int port) { + try { + sm.checkConnect(host, port); + } catch (SecurityException ex) { + log.warn("checkConnect(" + host + ", " + port + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkConnect(String host, int port, Object context) { + try { + sm.checkConnect(host, port, context); + } catch (SecurityException ex) { + log.warn("checkConnect(" + host + ", " + port + ", " + context + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkCreateClassLoader() { + try { + sm.checkCreateClassLoader(); + } catch (SecurityException ex) { + log.warn("checkCreateClassLoader(): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkDelete(String file) { + try { + sm.checkDelete(file); + } catch (SecurityException ex) { + log.warn("checkDelete(" + file + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkExec(String cmd) { + try { + sm.checkExec(cmd); + } catch (SecurityException ex) { + log.warn("checkExec(" + cmd + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkExit(int status) { + try { + sm.checkExit(status); + } catch (SecurityException ex) { + log.warn("checkExit(" + status + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkLink(String lib) { + try { + sm.checkLink(lib); + } catch (SecurityException ex) { + log.warn("checkLink(" + lib + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkListen(int port) { + try { + sm.checkListen(port); + } catch (SecurityException ex) { + log.warn("checkListen(" + port + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkMemberAccess(Class<?> clazz, int which) { + try { + sm.checkMemberAccess(clazz, which); + } catch (SecurityException ex) { + log.warn("checkMemberAccess(" + clazz + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkMulticast(InetAddress maddr) { + try { + sm.checkMulticast(maddr); + } catch (SecurityException ex) { + log.warn("checkMulticast(" + maddr + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkMulticast(InetAddress maddr, byte ttl) { + try { + sm.checkMulticast(maddr,ttl); + } catch (SecurityException ex) { + log.warn("checkMulticast(" + maddr + "," + ttl + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkPackageAccess(String pkg) { + try { + sm.checkPackageAccess(pkg); + } catch (SecurityException ex) { + log.warn("checkPackageAccess(" + pkg + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkPackageDefinition(String pkg) { + try { + sm.checkPackageDefinition(pkg); + } catch (SecurityException ex) { + log.warn("checkPackageDefinition(" + pkg + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkPermission(Permission perm) { + try { + sm.checkPermission(perm); + } catch (SecurityException ex) { + log.warn("checkPermission(" + perm.toString() + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkPermission(Permission perm, Object context) { + try { + sm.checkPermission(perm, context); + } catch (SecurityException ex) { + log.warn("checkPermission(" + perm.toString() + ", ctx): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkPrintJobAccess() { + try { + sm.checkPrintJobAccess(); + } catch (SecurityException ex) { + log.info("checkPrintJobAccess(): " + ex.getMessage(), ex); + throw ex; + } + } + + /** + * allowed + */ + @Override + public void checkPropertiesAccess() { + try { + sm.checkPropertiesAccess(); + } catch (SecurityException ex) { + log.info("checkPropertiesAccess(): " + ex.getMessage(), ex); + throw ex; + } + } + + /** + * access to all properties allowed + * @param key + */ + @Override + public void checkPropertyAccess(String key) { + try { + sm.checkPropertyAccess(key); + } catch (SecurityException ex) { + log.info("checkPropertyAccess(" + key + "): " + ex.getMessage()); + throw ex; + } + } + + @Override + public void checkRead(FileDescriptor fd) { + try { + sm.checkRead(fd); + } catch (SecurityException ex) { + log.warn("checkRead(" + fd + ") " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkRead(String file) { + try { + sm.checkRead(file); + } catch (SecurityException ex) { + log.warn("checkRead(" + file + ") " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkRead(String file, Object context) { + try { + sm.checkRead(file, context); + } catch (SecurityException ex) { + log.warn("checkRead(" + file + ") " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkSecurityAccess(String target) { + try { + sm.checkSecurityAccess(target); + } catch (SecurityException ex) { + log.info("checkSecurityAccess(" + target + "): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public void checkSetFactory() { + log.info("checkSetFactory() "); + try { + sm.checkSetFactory(); + } catch (SecurityException ex) { + log.warn("checkSetFactroy(): " + ex.getMessage(), ex); + throw ex; + } + + } + + @Override + public void checkSystemClipboardAccess() { + try { + sm.checkSystemClipboardAccess(); + } catch (SecurityException ex) { + log.info("checkSystemClipboardAccess(): " + ex.getMessage(), ex); + throw ex; + } + } + + @Override + public boolean checkTopLevelWindow(Object window) { + log.info("checkTopLevelWindow(Object window)"); + try { + return sm.checkTopLevelWindow(window); + } catch (SecurityException ex) { + log.warn("checkTopLevelWindow(" + window + "): " + ex.getMessage(), ex); + throw ex; + } + + } + + @Override + public void checkWrite(FileDescriptor fd) { + try { + sm.checkWrite(fd); + } catch (SecurityException ex) { + log.info("checkWrite(" + fd + "): " + ex.getMessage(), ex); + } + } + + @Override + public void checkWrite(String file) { + try { + sm.checkWrite(file); + } catch (SecurityException ex) { + log.info("checkWrite(" + file + "): " + ex.getMessage(), ex); + } + } + +// @Override +// protected int classDepth(String name) { +// log.info("classDepth(String name)"); return this.classDepth(name); +// } +// +// @Override +// protected int classLoaderDepth() { +// log.info("classLoaderDepth"); return sm.classLoaderDepth(); +// } +// +// @Override +// protected Object clone() throws CloneNotSupportedException { +// log.info("clone"); return sm.clone(); +// } +// +// @Override +// protected ClassLoader currentClassLoader() { +// log.info("currentClassLoader"); return sm.currentClassLoader(); +// } +// +// @Override +// protected Class<?> currentLoadedClass() { +// log.info("currentLoadedClass"); return sm.currentLoadedClass(); +// } + @Override + public boolean equals(Object obj) { + log.info("equals"); + return sm.equals(obj); + } + +// @Override +// protected void finalize() throws Throwable { +// log.info("finalize"); sm.finalize(); +// } +// @Override +// protected Class[] getClassContext() { +// log.info("getClassContext"); return sm.getClassContext(); +// } + @Override + public boolean getInCheck() { + log.info("getInCheck"); + return sm.getInCheck(); + } + + @Override + public Object getSecurityContext() { + log.info("getSecurityContext"); + return sm.getSecurityContext(); + } + + @Override + public ThreadGroup getThreadGroup() { + log.info("getThreadGroup"); + return sm.getThreadGroup(); + } + + @Override + public int hashCode() { + log.info("hashCode"); + return sm.hashCode(); + } + +// @Override +// protected boolean inClass(String name) { +// log.info("inClass"); return sm.inClass(name); +// } +// +// @Override +// protected boolean inClassLoader() { +// log.info(""); return sm.inClassLoader(); +// } + @Override + public String toString() { + log.info("toString"); + return sm.toString(); + } +} 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 9990b2a0..fb7c40dd 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,7 +36,7 @@ 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 TRAYICON_RESOURCE = "at/gv/egiz/bku/webstart/ui/trayicon_32.png"; public static final String TRAYMENU_SHUTDOWN = "TrayMenu.Shutdown"; public static final String TRAYMENU_TOOLTIP = "TrayMenu.Tooltip"; |