diff options
Diffstat (limited to 'netx/net/sourceforge/jnlp/security')
8 files changed, 1054 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityLevel.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityLevel.java new file mode 100644 index 0000000..59cb799 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityLevel.java @@ -0,0 +1,78 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +import net.sourceforge.jnlp.runtime.Translator; + +public enum AppletSecurityLevel { + + DENY_ALL, DENY_UNSIGNED, ASK_UNSIGNED, ALLOW_UNSIGNED; + + public static String allToString() { + return DENY_ALL.toChars() + " " + DENY_UNSIGNED.toChars() + " " + ASK_UNSIGNED.toChars() + " " + ALLOW_UNSIGNED.toChars(); + } + + public String toChars() { + return this.name(); + } + + public String toExplanation() { + switch (this) { + case DENY_ALL: + return Translator.R("APPEXTSECappletSecurityLevelExtraHighId") + " - " + Translator.R("APPEXTSECappletSecurityLevelExtraHighExplanation"); + case DENY_UNSIGNED: + return Translator.R("APPEXTSECappletSecurityLevelVeryHighId") + " - " + Translator.R("APPEXTSECappletSecurityLevelVeryHighExplanation"); + case ASK_UNSIGNED: + return Translator.R("APPEXTSECappletSecurityLevelHighId") + " - " + Translator.R("APPEXTSECappletSecurityLevelHighExplanation"); + case ALLOW_UNSIGNED: + return Translator.R("APPEXTSECappletSecurityLevelLowId") + " - " + Translator.R("APPEXTSECappletSecurityLevelLowExplanation"); + } + throw new RuntimeException("Unknown AppletSecurityLevel"); + } + + public static AppletSecurityLevel fromString(String s) { + return AppletSecurityLevel.valueOf(s.toUpperCase()); + } + + @Override + public String toString() { + return toExplanation(); + } + + public static AppletSecurityLevel getDefault() { + return ASK_UNSIGNED; + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletStartupSecuritySettings.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletStartupSecuritySettings.java new file mode 100644 index 0000000..2d82ed1 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletStartupSecuritySettings.java @@ -0,0 +1,97 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +import javax.naming.ConfigurationException; +import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel; +import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionStorage; +import net.sourceforge.jnlp.security.appletextendedsecurity.impl.UnsignedAppletActionStorageImpl; +import net.sourceforge.jnlp.config.DeploymentConfiguration; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.lockingfile.StorageIoException; + +public class AppletStartupSecuritySettings { + + private static final AppletStartupSecuritySettings instance = new AppletStartupSecuritySettings(); + private UnsignedAppletActionStorageImpl globalInstance; + private UnsignedAppletActionStorageImpl customInstance; + + public static AppletStartupSecuritySettings getInstance() { + return instance; + } + + public static AppletSecurityLevel getHardcodedDefaultSecurityLevel() { + return AppletSecurityLevel.getDefault(); + } + + /** + * + * @return storage with global items from /etc/ + */ + public UnsignedAppletActionStorage getUnsignedAppletActionGlobalStorage() { + if (globalInstance == null) { + globalInstance = new UnsignedAppletActionStorageImpl(DeploymentConfiguration.getAppletTrustGlobalSettingsPath()); + } + return globalInstance; + } + + /** + * + * @return storage with custom items from /home/ + */ + public UnsignedAppletActionStorage getUnsignedAppletActionCustomStorage() { + if (customInstance == null) { + customInstance = new UnsignedAppletActionStorageImpl(DeploymentConfiguration.getAppletTrustUserSettingsPath()); + } + return customInstance; + } + + /** + * + * @return user-set security level or default one if user-set do not exists + */ + public AppletSecurityLevel getSecurityLevel() { + DeploymentConfiguration conf = JNLPRuntime.getConfiguration(); + if (conf == null) { + throw new StorageIoException("JNLPRuntime configuration is null. Try to reinstall IcedTea-Web"); + } + String s = conf.getProperty(DeploymentConfiguration.KEY_SECURITY_LEVEL); + if (s == null) { + return getHardcodedDefaultSecurityLevel(); + } + return AppletSecurityLevel.fromString(s); + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteUnsignedApplet.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteUnsignedApplet.java new file mode 100644 index 0000000..ed410a4 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/ExecuteUnsignedApplet.java @@ -0,0 +1,90 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +import net.sourceforge.jnlp.runtime.Translator; + +public enum ExecuteUnsignedApplet { + + ALWAYS, NEVER, YES, NO; + + public String toChar() { + switch (this) { + case ALWAYS: + return "A"; + case NEVER: + return "N"; + case YES: + return "y"; + case NO: + return "n"; + } + throw new RuntimeException("Unknown ExecuteUnsignedApplet"); + } + + public String toExplanation() { + switch (this) { + case ALWAYS: + return Translator.R("APPEXTSECunsignedAppletActionAlways"); + case NEVER: + return Translator.R("APPEXTSECunsignedAppletActionNever"); + case YES: + return Translator.R("APPEXTSECunsignedAppletActionYes"); + case NO: + return Translator.R("APPEXTSECunsignedAppletActionNo"); + } + throw new RuntimeException("Unknown UnsignedAppletAction"); + } + + public static ExecuteUnsignedApplet fromString(String s) { + if (s.startsWith("A")) { + return ExecuteUnsignedApplet.ALWAYS; + } else if (s.startsWith("N")) { + return ExecuteUnsignedApplet.NEVER; + } else if (s.startsWith("y")) { + return ExecuteUnsignedApplet.YES; + } else if (s.startsWith("n")) { + return ExecuteUnsignedApplet.NO; + } else { + throw new RuntimeException("Unknown ExecuteUnsignedApplet for " + s); + } + } + + @Override + public String toString() { + return toChar() + " - " + toExplanation(); + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java new file mode 100644 index 0000000..44700c0 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java @@ -0,0 +1,174 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class UnsignedAppletActionEntry { + + private ExecuteUnsignedApplet unsignedAppletAction; + private Date timeStamp; + private UrlRegEx documentBase; + private UrlRegEx codeBase; + private List<String> archives; + + public static UnsignedAppletActionEntry createFromString(String s) { + String[] split = s.split("\\s+"); + UnsignedAppletActionEntry nw = new UnsignedAppletActionEntry( + ExecuteUnsignedApplet.fromString(split[0]), + new Date(new Long(split[1])), + new UrlRegEx(split[2]), + null, + null); + if (split.length > 3) { + nw.setCodeBase(new UrlRegEx(split[3])); + } + if (split.length > 4) { + nw.setArchives(createArchivesList(s.substring(s.lastIndexOf(split[3]) + split[3].length()).trim())); + } + return nw; + } + + public UnsignedAppletActionEntry(ExecuteUnsignedApplet unsignedAppletAction, Date timeStamp, UrlRegEx documentBase, UrlRegEx codeBase, List<String> archives) { + this.unsignedAppletAction = unsignedAppletAction; + this.timeStamp = timeStamp; + this.documentBase = documentBase; + this.codeBase = codeBase; + this.archives = archives; + + } + + @Override + public String toString() { + return this.serializeToReadableAndParseableString(); + + } + + public void write(Writer bw) throws IOException { + bw.write(this.serializeToReadableAndParseableString()); + } + + private String serializeToReadableAndParseableString() { + return unsignedAppletAction.toChar() + + " " + ((timeStamp == null) ? "1" : timeStamp.getTime()) + + " " + ((documentBase == null) ? "" : documentBase.getRegEx()) + + " " + ((codeBase == null) ? "" : codeBase.getRegEx()) + + " " + createArchivesString(archives); + } + + public Date getTimeStamp() { + return timeStamp; + } + + public UrlRegEx getDocumentBase() { + return documentBase; + } + + public void setTimeStamp(Date timeStamp) { + this.timeStamp = timeStamp; + } + + public void setDocumentBase(UrlRegEx documentBase) { + this.documentBase = documentBase; + } + + public ExecuteUnsignedApplet getUnsignedAppletAction() { + return unsignedAppletAction; + } + + public void setUnsignedAppletAction(ExecuteUnsignedApplet unsignedAppletAction) { + this.unsignedAppletAction = unsignedAppletAction; + } + + public UrlRegEx getCodeBase() { + return codeBase; + } + + public void setCodeBase(UrlRegEx codeBase) { + this.codeBase = codeBase; + } + + public List<String> getArchives() { + return archives; + } + + public void setArchives(List<String> archives) { + this.archives = archives; + } + + public static String createArchivesString(List<String> listOfArchives) { + if (listOfArchives == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < listOfArchives.size(); i++) { + String string = listOfArchives.get(i); + if (string.trim().isEmpty()) { + continue; + } + sb.append(string); + if (i != listOfArchives.size() - 1) { + sb.append(","); + } + } + return sb.toString(); + } + + public static List<String> createArchivesList(String commedArchives) { + if (commedArchives == null) { + return null; + } + if (commedArchives.trim().isEmpty()) { + return null; + } + String[] items = commedArchives.trim().split(","); + List<String> r = new ArrayList<String>(items.length); + for (int i = 0; i < items.length; i++) { + String string = items[i]; + if (string.trim().isEmpty()) { + continue; + } + r.add(string); + + } + return r; + + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java new file mode 100644 index 0000000..8ce6500 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java @@ -0,0 +1,125 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +import java.util.List; + + +/** + * This is abstract access to white/blacklist created from some permanent storage. + * + * It is daclaring adding, updating and searching. Intentionally not removing as + * during plugin runtime no deletations should be done. + * + * Implementations of this interface (unless dummy ones:) should ensure correct + * communication with permanent storage and be prepared for multiple instances + * read/write the same storage at time + * + */ +public interface UnsignedAppletActionStorage { + + /** + * This methods iterates through records in + * DeploymentConfiguration.getAppletTrustSettingsPath(), and is mathing + * regexes saved here against params. so parameters here are NOR tegexes, + * but are matched against saved regexes + * + * Null or empty values are dangerously ignored, user, be aware of it. eg: + * match only codeBase will be null someCodeBase null null match only + * documentBase will be someDocBase null null null match only applet not + * regarding code or document base will be null null mainClass archives + * + * @param documentBase + * @param codeBase + * @param mainClass + * @param archives + * @return + */ + public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives); + + /** + * Shortcut getMatchingItem(documentBase, null,null,null) + * + * @param documentBase + * @return + */ + public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase); + + /** + * Shortcut getMatchingItem(null, codeBase,null,null) + * + * @param codeBase + * @return + */ + public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase); + + /** + * Shortcut getMatchingItem(documentBase, codeBase,null,null) + * + * @param documentBase + * @param codeBase + * @return + */ + public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase); + + /** + * Will add new record. Note that regexes are stored for bases matching. + * + * eg UnsignedAppletActionEntry which will deny some applet no matter of + * page will be new UnsignedAppletActionEntry(UnsignedAppletAction.NEVER, + * new Date(), null, null, someMain, someArchives) + * + * eg UnsignedAppletActionEntry which will allow all applets on page with + * same codebase will be new + * UnsignedAppletActionEntry(UnsignedAppletAction.NEVER, new Date(), ".*", + * ".*", null, null); + * + * @param item + */ + public void add(final UnsignedAppletActionEntry item); + + /** + * Will replace (current impl is matching by object's hashcode This is not + * reloading the list(but still saving after), so StorageIoEception can be + * thrown if it was not loaded before. + * + * Imho this should be used only to actualise timestamps or change + * UnsignedAppletAction + * + * @param item + */ + public void update(final UnsignedAppletActionEntry item); +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java new file mode 100644 index 0000000..f71f82a --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UrlRegEx.java @@ -0,0 +1,62 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity; + +public class UrlRegEx { + + String regEx; + + public UrlRegEx(String s) { + regEx = s; + } + + @Override + public String toString() { + return getRegEx(); + } + + public String getRegEx() { + return regEx; + } + + public String getFilteredRegEx() { + return regEx.replaceAll("\\\\Q", "").replaceAll("\\\\E", ""); + } + + public void setRegEx(String regEx) { + this.regEx = regEx; + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java new file mode 100644 index 0000000..66e16ee --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java @@ -0,0 +1,188 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity.impl; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteUnsignedApplet; +import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry; +import net.sourceforge.jnlp.security.appletextendedsecurity.UrlRegEx; +import net.sourceforge.jnlp.util.lockingfile.StorageIoException; + +public class UnsignedAppletActionStorageExtendedImpl extends UnsignedAppletActionStorageImpl { + + public UnsignedAppletActionStorageExtendedImpl(String location) { + this(new File(location)); + } + + public UnsignedAppletActionStorageExtendedImpl(File location) { + super(location); + } + + public UnsignedAppletActionEntry[] toArray() { + lock(); + try { + readContents(); + return items.toArray(new UnsignedAppletActionEntry[items.size()]); + } catch (IOException e) { + throw new StorageIoException(e); + } finally { + unlock(); + } + } + + public void clear() { + doLocked(new Runnable() { + public void run() { + try { + items.clear(); + writeContents(); + } catch (IOException e) { + throw new StorageIoException(e); + } + } + }); + } + + public void removeByBehaviour(final ExecuteUnsignedApplet unsignedAppletAction) { + doLocked(new Runnable() { + public void run() { + try { + readContents(); + for (int i = 0; i < items.size(); i++) { + UnsignedAppletActionEntry unsignedAppletActionEntry = items.get(i); + if (unsignedAppletActionEntry.getUnsignedAppletAction() == unsignedAppletAction) { + items.remove(i); + i--; + } + + } + writeContents(); + } catch (IOException e) { + throw new StorageIoException(e); + } + } + }); + } + + private void swap(final int i, final int ii) { + doLocked(new Runnable() { + public void run() { + try { + readContents(); + UnsignedAppletActionEntry backup = items.get(i); + items.set(i, items.get(ii)); + items.set(ii, backup); + writeContents(); + } catch (IOException e) { + throw new StorageIoException(e); + } + } + }); + + } + + public int moveUp(int selectedRow) { + if (selectedRow <= 0) { + return selectedRow; + } + swap(selectedRow, selectedRow - 1); + return selectedRow-1; + } + + public int moveDown(int selectedRow) { + if (selectedRow >= items.size() - 1) { + return selectedRow; + } + swap(selectedRow, selectedRow + 1); + return selectedRow+1; + } + + public void remove(final int item) { + doLocked(new Runnable() { + public void run() { + try { + readContents(); + items.remove(item); + writeContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }); + } + + public void modify(final UnsignedAppletActionEntry source, final int columnIndex, final Object aValue) { + Runnable r = new Runnable() { + public void run() { + + try { + if (!items.contains(source)) { + throw new StorageIoException("Item to be modified not found in storage"); + } + + if (columnIndex == 0) { + source.setUnsignedAppletAction((ExecuteUnsignedApplet) aValue); + } + if (columnIndex == 1) { + source.setTimeStamp((Date) aValue); + } + if (columnIndex == 2) { + source.setDocumentBase(new UrlRegEx((String) aValue)); + } + if (columnIndex == 3) { + source.setCodeBase(new UrlRegEx((String) aValue)); + } + if (columnIndex == 4) { + source.setArchives(UnsignedAppletActionEntry.createArchivesList((String) aValue)); + } + + writeContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }; + doLocked(r); + + } + + @Override + public synchronized void writeContentsLocked() throws IOException { + super.writeContentsLocked(); + } +} diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java new file mode 100644 index 0000000..7f71b50 --- /dev/null +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java @@ -0,0 +1,240 @@ +/* Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.security.appletextendedsecurity.impl; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteUnsignedApplet; +import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry; +import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionStorage; +import net.sourceforge.jnlp.util.lockingfile.LockingReaderWriter; +import net.sourceforge.jnlp.util.lockingfile.StorageIoException; + +public class UnsignedAppletActionStorageImpl extends LockingReaderWriter implements UnsignedAppletActionStorage { + + protected List<UnsignedAppletActionEntry> items; + + public UnsignedAppletActionStorageImpl(String location) { + this(new File(location)); + } + + public UnsignedAppletActionStorageImpl(File location) { + super(location); + } + + @Override + public void writeContents() throws IOException { + super.writeContents(); + } + + @Override + public synchronized void writeContentsLocked() throws IOException { + super.writeContentsLocked(); + } + + @Override + protected void readContents() throws IOException { + if (items == null) { + items = new ArrayList<UnsignedAppletActionEntry>(); + } else { + items.clear(); + } + super.readContents(); + } + + @Override + protected void readLine(String line) { + if (line.trim().length() != 0) { + this.items.add(UnsignedAppletActionEntry.createFromString(line)); + } + } + + @Override + public void writeContent(BufferedWriter bw) throws IOException { + for (UnsignedAppletActionEntry item : items) { + item.write(bw); + bw.newLine(); + } + } + + @Override + public void add(final UnsignedAppletActionEntry item) { + doLocked(new Runnable() { + @Override + public void run() { + try { + readContents(); + items.add(item); + writeContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }); + } + + @Override + public void update(final UnsignedAppletActionEntry item) { + doLocked(new Runnable() { + @Override + public void run() { + try { + if (items == null) { + throw new StorageIoException("Storage is not initialised, can not update"); + } + if (!items.contains(item)) { + throw new StorageIoException("Storage does not contain item you are updating. can not update"); + } + writeContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }); + } + + @Override + public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives) { + List<UnsignedAppletActionEntry> results = getMatchingItems(documentBase, codeBase, archives); + if (results == null || results.isEmpty()) { + return null; + } + // Chose the first result, unless we find a 'stronger' result + // Actions such as 'always accept' or 'always reject' are 'stronger' than + // the hints 'was accepted' or 'was rejected'. + for (UnsignedAppletActionEntry candidate : results) { + if (candidate.getUnsignedAppletAction() == ExecuteUnsignedApplet.ALWAYS + || candidate.getUnsignedAppletAction() == ExecuteUnsignedApplet.NEVER) { + //return first found strong + return candidate; + } + } + //no strong found, return first + return results.get(0); + } + + public List<UnsignedAppletActionEntry> getMatchingItems(String documentBase, String codeBase, List<String> archives) { + List<UnsignedAppletActionEntry> result = new ArrayList(); + lock(); + try { + readContents(); + if (items == null) { + return result; + } + for (UnsignedAppletActionEntry unsignedAppletActionEntry : items) { + if (isMatching(unsignedAppletActionEntry, documentBase, codeBase, archives)) { + result.add(unsignedAppletActionEntry); + } + } + } catch (IOException e) { + throw new StorageIoException(e); + } finally { + unlock(); + } + return result; + } + + private boolean isMatching(UnsignedAppletActionEntry unsignedAppletActionEntry, String documentBase, String codeBase, List<String> archives) { + boolean result = true; + if (documentBase != null && !documentBase.trim().isEmpty()) { + result = result && documentBase.matches(unsignedAppletActionEntry.getDocumentBase().getRegEx()); + } + if (codeBase != null && !codeBase.trim().isEmpty()) { + result = result && codeBase.matches(unsignedAppletActionEntry.getCodeBase().getRegEx()); + } + if (archives != null) { + result = result && compareArchives(archives, unsignedAppletActionEntry.getArchives()); + } + return result; + } + + @Override + public String toString() { + return getBackingFile() + " " + super.toString(); + } + + private boolean compareArchives(List<String> archives, List<String> saved) { + if (archives == null && saved !=null){ + return false; + } + if (archives != null && saved ==null){ + return false; + } + if (archives == null && saved ==null){ + return true; + } + if (archives.size() != saved.size()) { + return false; + } + Collections.sort(archives); + Collections.sort(saved); + for (int i = 0; i < saved.size(); i++) { + String string1 = saved.get(i); + String string2 = archives.get(i); + //intentional reference compare + if (string1 == string2) { + continue; + } + if (string1 == null || string2 == null) { + return false; + } + if (string1.trim().equals(string2.trim())) { + continue; + } + return false; + } + return true; + } + + @Override + public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase) { + return getMatchingItem(documentBase, null, null); + } + + @Override + public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase) { + return getMatchingItem(null, codeBase, null); + } + + @Override + public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase) { + return getMatchingItem(documentBase, codeBase, null); + } +} |