[fyi][icedtea-web] backend and itw-settings for extended applets security
Adam Domurad
adomurad at redhat.com
Tue Feb 5 07:08:24 PST 2013
On 02/03/2013 07:08 AM, Jiri Vanek wrote:
> Whole troubles are described here
http://icedtea.classpath.org/wiki/Extended_Applets_Security rather then
in plain email.
>
> There is what me and adam have already achieved on this topic, what
we have o achieve and where we are stil not so sure....
>
> This patch is containing itw-settings part and backend for
manipulating stored entries.and basic matching.
> I noted this just [fyi] because adam ave already walked through the
patch, and so have I across his part. So the patch should be ready for
push unless someone find something malicious on implementation or even
on design.
>
> J.
Typos only / misspellings only.
> diff -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/AppletExtendedSecurity.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/AppletExtendedSecurity.java Fri
Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,84 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.appletextendedsecurity;
> +
> +import javax.naming.ConfigurationException;
> +import
net.sourceforge.appletextendedsecurity.impl.UnsignedAppletActionStorageImpl;
> +import net.sourceforge.jnlp.config.DeploymentConfiguration;
> +import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +
> +
> +public class AppletExtendedSecurity {
> +
> + private static UnsignedAppletActionStorageImpl globalInstance;
> + private static UnsignedAppletActionStorageImpl customInstance;
> +
> + /**
> + *
> + * @return storage with global items from /etc/
> + */
> +
> + public static UnsignedAppletActionStorage
getUnsignedAppletActionGlobalStorage(){
> + if (globalInstance == null){
> + globalInstance = new
UnsignedAppletActionStorageImpl(DeploymentConfiguration.getAppletTrustGlobalSettingsPath());
> + }
> + return globalInstance;
> + }
> +
> +
> + /**
> + *
> + * @return storage with custom items from /home/
> + */
> + public static UnsignedAppletActionStorage
getUnsignedAppletActionCustomStorage(){
> + if (customInstance == null){
> + customInstance = new
UnsignedAppletActionStorageImpl(DeploymentConfiguration.getAppletTrustCustomSettingsPath());
> + }
> + return customInstance;
> + }
> +
> + public static AppletSecurityLevel getDefaultSecurityLevel(){
> + return AppletSecurityLevel.getDefault();
> + }
> +
> + /**
> + *
> + * @return user-set seurity level or default one if user-set do
not exists
s/seurity/security/
> + */
> + public static AppletSecurityLevel getCustomSecurityLevel(){
> + DeploymentConfiguration conf = JNLPRuntime.getConfiguration();
> + if (conf==null){
> + conf = new DeploymentConfiguration();
> + try {
> + conf.load();
> + } catch (ConfigurationException ex){
> + ex.printStackTrace();
> + return getDefaultSecurityLevel();
> + }
> + }
> + String s =
conf.getProperty(DeploymentConfiguration.KEY_SECURITY_LEVEL);
> + if (s==null) {
> + return getDefaultSecurityLevel();
> + }
> + return AppletSecurityLevel.fromString(s);
> + }
> +
> +
> +
> +}
> diff -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/AppletSecurityLevel.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/AppletSecurityLevel.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,83 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.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() {
> + switch (this) {
> + case DENY_ALL:
> + return " DENY_ALL";
> + case DENY_UNSIGNED:
> + return "DENY_UNSIGNED";
> + case ASK_UNSIGNED:
> + return "ASK_UNSIGNED";
> + case ALLOW_UNSIGNED:
> + return "ALLOW_UNSIGNED";
> + }
> + throw new RuntimeException("Unknown AppletSecurityLevel");
> + }
> +
> + 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) {
> + if (s.trim().equalsIgnoreCase("DENY_ALL")) {
> + return AppletSecurityLevel.DENY_ALL;
> + } else if (s.trim().equalsIgnoreCase("DENY_UNSIGNED")) {
> + return AppletSecurityLevel.DENY_UNSIGNED;
> + } else if (s.trim().equalsIgnoreCase("ASK_UNSIGNED")) {
> + return AppletSecurityLevel.ASK_UNSIGNED;
> + } else if (s.trim().equalsIgnoreCase("ALLOW_UNSIGNED")) {
> + return AppletSecurityLevel.ALLOW_UNSIGNED;
> + } else {
> + throw new RuntimeException("Unknown AppletSecurityLevel
for " + s);
> + }
> + }
> +
> + @Override
> + public String toString() {
> + return toExplanation();
> + }
> +
> + public static AppletSecurityLevel getDefault(){
> + return ASK_UNSIGNED;
> + }
> +}
> diff -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/UnsignedAppletAction.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/UnsignedAppletAction.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,73 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.appletextendedsecurity;
> +
> +import net.sourceforge.jnlp.runtime.Translator;
> +
> +public enum UnsignedAppletAction {
> +
> + 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 UnsignedAppletAction");
> + }
> +
> + 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 UnsignedAppletAction fromString(String s) {
> + if (s.startsWith("A")) {
> + return UnsignedAppletAction.ALWAYS;
> + } else if (s.startsWith("N")) {
> + return UnsignedAppletAction.NEVER;
> + } else if (s.startsWith("y")) {
> + return UnsignedAppletAction.YES;
> + } else if (s.startsWith("n")) {
> + return UnsignedAppletAction.NO;
> + } else {
> + throw new RuntimeException("Unknown UnsignedAppletAction
for " + s);
> + }
> + }
> +
> + @Override
> + public String toString() {
> + return toChar() + " - " + toExplanation();
> + }
> +}
> diff -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/UnsignedAppletActionEntry.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/UnsignedAppletActionEntry.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,169 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +package net.sourceforge.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 UnsignedAppletAction unsignedAppletAction;
> + private Date timeStamp;
> + private UrlRegEx documentBase;
> + private UrlRegEx codeBase;
> + private String mainClass;
> + private List<String> archives;
> +
> +
> + public static UnsignedAppletActionEntry createFromString(String s) {
> + String[] split = s.split("\\s+");
> + UnsignedAppletActionEntry nw = new UnsignedAppletActionEntry(
> + UnsignedAppletAction.fromString(split[0]),
> + new Date(new Long(split[1])),
> + new UrlRegEx(split[2]),
> + null,
> + null,
> + null
> + );
> + if (split.length>3){
> + nw.setCodeBase(new UrlRegEx(split[3]));
> + }
> + if (split.length>4){
> + nw.setMainClass(split[4]);
> + }
> + if (split.length>5){
> +
nw.setArchives(createArchivesList(s.substring(s.indexOf(split[4])+split[4].length()).trim()));
> + }
> + return nw;
> + }
> +
> + public UnsignedAppletActionEntry(UnsignedAppletAction
unsignedAppletAction, Date timeStamp, UrlRegEx documentBase, UrlRegEx
codeBase, String mainClass, List<String> archives) {
> + this.unsignedAppletAction = unsignedAppletAction;
> + this.timeStamp = timeStamp;
> + this.documentBase = documentBase;
> + this.codeBase = codeBase;
> + this.mainClass = mainClass;
> + this.archives = archives;
> +
> + }
> +
> +
> +
> + @Override
> + public String toString() {
> + return unsignedAppletAction.toChar() +
> + " " + ((timeStamp == null)?"1":timeStamp.getTime()) +
> + " " + ((documentBase ==
null)?"":documentBase.getRegEx()) +
> + " " + ((codeBase == null)?"":codeBase.getRegEx()) +
> + " " + ((mainClass == null)?"":mainClass) +
> + " " + createArchivesString(archives);
> +
> + }
> +
> + public void write(Writer bw) throws IOException {
> + bw.write(this.toString());
> + }
> +
> + 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 UnsignedAppletAction getUnsignedAppletAction() {
> + return unsignedAppletAction;
> + }
> +
> + public void setUnsignedAppletAction(UnsignedAppletAction
unsignedAppletAction) {
> + this.unsignedAppletAction = unsignedAppletAction;
> + }
> +
> + public UrlRegEx getCodeBase() {
> + return codeBase;
> + }
> +
> + public void setCodeBase(UrlRegEx codeBase) {
> + this.codeBase = codeBase;
> + }
> +
> + public String getMainClass() {
> + return mainClass;
> + }
> +
> + public void setMainClass(String mainClass) {
> + this.mainClass = mainClass;
> + }
> +
> + 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).append(";");
> + }
> + return sb.toString();
> + }
> + public static List<String> createArchivesList(String
semicolonedArchives) {
> + if (semicolonedArchives == null) return null;
> + if (semicolonedArchives.trim().isEmpty()) return null;
> + String[] items = semicolonedArchives.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 -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/UnsignedAppletActionStorage.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/UnsignedAppletActionStorage.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,106 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*//*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +package net.sourceforge.appletextendedsecurity;
> +
> +import java.util.List;
> +
> +/**
> + *
> + * @author jvanek
> + */
> +public interface UnsignedAppletActionStorage {
> +
> +
> + /**
> + * This methods iterates through record in
DeploymentConfiguration.getAppletTrustSettingsPath(),
s/record/records/
> + * and is mathing regexes saved here against params. so
parameters here are NOR tegexes,
s/mathing/matching/
s/NOR/NOT/
s/tegexes/regexes/
> + * 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 mainClas archives
s/mainClas/mainClass/
> + * @param documentBase
> + * @param codeBase
> + * @param mainClass
> + * @param archives
> + * @return
> + */
> + public UnsignedAppletActionEntry getMatchingItem(String
documentBase, String codeBase, String mainClass, 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 dany some applet no
metter of page will be
s/dany/deny/
s/metter/matter/
> + * 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 -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/UrlRegEx.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/appletextendedsecurity/UrlRegEx.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,47 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.appletextendedsecurity;
> +
> +public class UrlRegEx {
> +
> + String regEx;
> + //cache pattern during each set and init?
> + //Pattern p
> +
> + 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 -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,220 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.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.appletextendedsecurity.UnsignedAppletActionEntry;
> +import
net.sourceforge.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 do not
contains item you are updateing. can not update");
s/do not contains/does not contain/
s/updateing/updating/
> + }
> + writeContents();
> + } catch (IOException ex) {
> + throw new StorageIoException(ex);
> + }
> + }
> + });
> + }
> +
> +
> +
> + @Override
> + public UnsignedAppletActionEntry getMatchingItem(String
documentBase, String codeBase, String mainClass, List<String> archives) {
> + List<UnsignedAppletActionEntry> result =
getMatchingItems(documentBase, codeBase, mainClass, archives);
> + if (result == null || result.isEmpty()) {
> + return null;
> + }
> + //returns first item
> + return result.get(0);
> + //Or longest match??
> + }
> +
> + public List<UnsignedAppletActionEntry> getMatchingItems(String
documentBase, String codeBase, String mainClass, 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,mainClass,archives)){
> + result.add(unsignedAppletActionEntry);
> + }
> + }
> + return null;
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + return result;
> + }
> + }
> +
> + private boolean isMatching(UnsignedAppletActionEntry
unsignedAppletActionEntry, String documentBase, String codeBase, String
mainClass, 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 (mainClass != null && !mainClass.trim().isEmpty()) {
> + result = result &&
mainClass.equals(unsignedAppletActionEntry.getMainClass());
> + }
> +
> + if (archives != null) {
> + result = result && comapreArchives(archives,
unsignedAppletActionEntry.getArchives());
> + }
> + return result;
> + }
> +
> + @Override
> + public String toString() {
> + return getBackingFile()+" "+super.toString();
> + }
> +
> + private boolean comapreArchives(List<String> archives,
List<String> saved) {
> + 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, null);
> + }
> +
> + @Override
> + public UnsignedAppletActionEntry
getMatchingItemByCodeBase(String codeBase) {
> + return getMatchingItem(null, codeBase, null, null);
> + }
> +
> + @Override
> + public UnsignedAppletActionEntry getMatchingItemByBases(String
documentBase, String codeBase) {
> + return getMatchingItem(documentBase, codeBase, null, null);
> + }
> +
> +
> +
> +
> +}
> diff -r e631770d76ba
netx/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageOperator.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageOperator.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,180 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.appletextendedsecurity.impl;
> +
> +import java.io.File;
> +import java.io.IOException;
> +import java.util.Date;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletAction;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletActionEntry;
> +import net.sourceforge.appletextendedsecurity.UrlRegEx;
> +import net.sourceforge.jnlp.util.lockingfile.StorageIoException;
> +
> +public class UnsignedAppletActionStorageOperator extends
UnsignedAppletActionStorageImpl {
> +
> +
> + public UnsignedAppletActionStorageOperator(String location) {
> + this(new File(location));
> + }
> +
> + public UnsignedAppletActionStorageOperator(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 UnsignedAppletAction
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 void moveUp(int selectedRow) {
> + if (selectedRow <= 0) {
> + return;
> + }
> + swap(selectedRow, selectedRow - 1);
> + }
> +
> + public void moveDown(int selectedRow) {
> + if (selectedRow >= items.size() - 1) {
> + return;
> + }
> + swap(selectedRow, 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((UnsignedAppletAction) 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.setMainClass((String) aValue);
> + }
> + if (columnIndex == 5) {
> +
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 -r e631770d76ba netx/net/sourceforge/jnlp/config/Defaults.java
> --- a/netx/net/sourceforge/jnlp/config/Defaults.java Thu Jan 31
11:12:35 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/config/Defaults.java Fri Feb 01
20:55:48 2013 +0100
> @@ -42,6 +42,7 @@
> import java.io.File;
> import java.util.HashMap;
> import java.util.Map;
> +import net.sourceforge.appletextendedsecurity.AppletSecurityLevel;
>
> import net.sourceforge.jnlp.ShortcutDesc;
> import net.sourceforge.jnlp.runtime.JNLPProxySelector;
> @@ -384,6 +385,41 @@
> DeploymentConfiguration.KEY_PLUGIN_JVM_ARGUMENTS,
> null,
> null
> + },
> + //unsigned applet security level
> + {
> + DeploymentConfiguration.KEY_SECURITY_LEVEL,
> + new ValueValidator() {
> +
> + @Override
> + public void validate(Object value) throws
IllegalArgumentException {
> + if (value == null) {
> + throw new
IllegalArgumentException("Value can't be null");
> + }
> + if (value instanceof AppletSecurityLevel) {
> + //??
> + return;
> + }
> + if (!(value instanceof String)) {
> + throw new
IllegalArgumentException("Expected was String, was " + value.getClass());
> + }
> + try {
> + AppletSecurityLevel validated =
AppletSecurityLevel.fromString((String) value);
> + if (validated == null) {
> + throw new
IllegalArgumentException("Result can't be null, was");
> + }
> + //thrown by fromString
> + } catch (RuntimeException ex) {
> + throw new IllegalArgumentException(ex);
> + }
> + }
> +
> + @Override
> + public String getPossibleValues() {
> + return AppletSecurityLevel.allToString();
> + }
> + },
> + null
> }
> };
>
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java
> --- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java
Thu Jan 31 11:12:35 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -51,6 +51,7 @@
> public static final String DEPLOYMENT_DIR = ".icedtea";
> public static final String DEPLOYMENT_CONFIG = "deployment.config";
> public static final String DEPLOYMENT_PROPERTIES =
"deployment.properties";
> + public static final String APPLET_TRUST_SETTINGS =
".appletTrustSettings";
>
> public static final String DEPLOYMENT_COMMENT = "Netx deployment
configuration";
>
> @@ -105,6 +106,9 @@
> /** Boolean. Only show security prompts to user if true */
> public static final String KEY_SECURITY_PROMPT_USER =
"deployment.security.askgrantdialog.show";
>
> + //enum of AppletSecurityLevel in result
> + public static final String KEY_SECURITY_LEVEL =
"deployment.security.level";
> +
> public static final String KEY_SECURITY_TRUSTED_POLICY =
"deployment.security.trusted.policy";
>
> /** Boolean. Only give
AWTPermission("showWindowWithoutWarningBanner") if true */
> @@ -196,6 +200,17 @@
> load(true);
> }
>
> + public static File getAppletTrustCustomSettingsPath() {
> + return new File(System.getProperty("user.home") +
File.separator + DEPLOYMENT_DIR
> + + File.separator + APPLET_TRUST_SETTINGS);
> + }
> +
> + public static File getAppletTrustGlobalSettingsPath() {
> + return new File(File.separator + "etc" + File.separator +
".java" + File.separator
> + + "deployment" + File.separator +
APPLET_TRUST_SETTINGS);
> +
> + }
> +
> /**
> * Initialize this deployment configuration by reading
configuration files.
> * Generally, it will try to continue and ignore errors it finds
(such as file not found).
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java
> --- a/netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java Thu
Jan 31 11:12:35 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java Fri
Feb 01 20:55:48 2013 +0100
> @@ -41,6 +41,7 @@
> import javax.swing.JFrame;
> import javax.swing.JLabel;
> import javax.swing.JList;
> +import javax.swing.JOptionPane;
> import javax.swing.JPanel;
> import javax.swing.JScrollPane;
> import javax.swing.SwingConstants;
> @@ -230,7 +231,10 @@
> new SettingsPanel(Translator.R("CPTabNetwork"),
createNetworkSettingsPanel()),
> // TODO: This is commented out since this is not
implemented yet
> // new SettingsPanel(Translator.R("CPTabRuntimes"),
createRuntimesSettingsPanel()),
> - new SettingsPanel(Translator.R("CPTabSecurity"),
createSecuritySettingsPanel()), };
> + new SettingsPanel(Translator.R("CPTabSecurity"),
createSecuritySettingsPanel()),
> + //todo refactor to work with tmp file and apply as
asu designed it
> + new
SettingsPanel(Translator.R("APPEXTSECControlPanelExtendedAppletSecurityTitle"),
new
UnsignedAppletsTrustingListPanel(DeploymentConfiguration.getAppletTrustGlobalSettingsPath(),DeploymentConfiguration.getAppletTrustCustomSettingsPath(),
this.config) )
> + };
>
> // Add panels.
> final JPanel settingsPanel = new JPanel(new CardLayout());
> @@ -360,6 +364,7 @@
> config.save();
> } catch (IOException e) {
> e.printStackTrace();
> + JOptionPane.showMessageDialog(this, e);
> }
> }
>
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,168 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.jnlp.controlpanel;
> +
> +import java.util.Date;
> +import javax.swing.table.AbstractTableModel;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletAction;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletActionEntry;
> +import net.sourceforge.appletextendedsecurity.UrlRegEx;
> +import
net.sourceforge.appletextendedsecurity.impl.UnsignedAppletActionStorageOperator;
> +import net.sourceforge.jnlp.runtime.Translator;
> +
> +public class UnsignedAppletActionTableModel extends AbstractTableModel {
> +
> + final UnsignedAppletActionStorageOperator back;
> + private final String[] columns = new
String[]{Translator.R("APPEXTSECguiTableModelTableColumnAction"),
> + Translator.R("APPEXTSECguiTableModelTableColumnDateOfAction"),
> + Translator.R("APPEXTSECguiTableModelTableColumnDocumentBase"),
> + Translator.R("APPEXTSECguiTableModelTableColumnCodeBase"),
> + Translator.R("APPEXTSECguiTableModelTableColumnMainClass"),
> + Translator.R("APPEXTSECguiTableModelTableColumnArchives")};
> +
> + public
UnsignedAppletActionTableModel(UnsignedAppletActionStorageOperator back) {
> + this.back = back;
> + }
> +
> + @Override
> + public int getRowCount() {
> + try {
> + return back.toArray().length;
> + } catch (Exception ex) {
> + throw new RuntimeException(ex);
> + }
> + }
> +
> + @Override
> + public int getColumnCount() {
> + return columns.length;
> + }
> +
> + @Override
> + public String getColumnName(int columnIndex) {
> + return columns[columnIndex];
> + }
> +
> + @Override
> + public Class<?> getColumnClass(int columnIndex) {
> + if (columnIndex == 0) {
> + return UnsignedAppletAction.class;
> + }
> + if (columnIndex == 1) {
> + return Date.class;
> + }
> + if (columnIndex == 2) {
> + return UrlRegEx.class;
> + }
> + if (columnIndex == 3) {
> + return UrlRegEx.class;
> + }
> + if (columnIndex == 3) {
> + return String.class;
> + }
> + if (columnIndex == 3) {
> + return String.class;
> + }
> + return Object.class;
> + }
> +
> + @Override
> + public boolean isCellEditable(int rowIndex, int columnIndex) {
> + if (back.isReadOnly()){
> + return false;
> + }
> + if (columnIndex==1) return false;
> + if (columnIndex==0) return true;
> + if (getValueAt(rowIndex, columnIndex-1)==null ||
getValueAt(rowIndex, columnIndex-1).toString().trim().isEmpty()) return
false;
> + return true;
> + }
> +
> + @Override
> + public Object getValueAt(int rowIndex, int columnIndex) {
> +
> + UnsignedAppletActionEntry source = back.toArray()[rowIndex];
> + if (columnIndex == 0) {
> + return source.getUnsignedAppletAction();
> + }
> + if (columnIndex == 1) {
> + return source.getTimeStamp();
> + }
> + if (columnIndex == 2) {
> + return source.getDocumentBase();
> + }
> + if (columnIndex == 3) {
> + return source.getCodeBase();
> + }
> + if (columnIndex == 4) {
> + return source.getMainClass();
> + }
> + if (columnIndex == 5) {
> + return
UnsignedAppletActionEntry.createArchivesString(source.getArchives());
> + }
> + return null;
> + }
> +
> + @Override
> + public void setValueAt(final Object aValue, final int rowIndex,
final int columnIndex) {
> + final UnsignedAppletActionEntry source =
back.toArray()[rowIndex];
> + back.modify(source, columnIndex, aValue);
> +
> + }
> +
> + public void addRow() {
> + int i = back.toArray().length;
> + String s = "\\Qhttp://localhost:80/\\E.*";
> + back.add(new UnsignedAppletActionEntry(
> + UnsignedAppletAction.NEVER,
> + new Date(),
> + new UrlRegEx(s),
> + new UrlRegEx(s),
> + null,
> + null));
> + fireTableRowsInserted(i, i + 1);
> + }
> +
> + public void removeRow(int i) {
> + back.remove(i);
> + fireTableRowsDeleted(i, i);
> + }
> +
> + public void clear() {
> + int i = getRowCount();
> + back.clear();
> + fireTableRowsDeleted(0, i);
> + }
> +
> + void removeByBehaviour(UnsignedAppletAction unsignedAppletAction) {
> + int i = getRowCount();
> + back.removeByBehaviour(unsignedAppletAction);
> + fireTableRowsDeleted(0, i);
> + }
> +
> + void moveUp(int selectedRow) {
> + int i = getRowCount();
> + back.moveUp(selectedRow);
> + fireTableRowsUpdated(i-1, i);
> + }
> + void moveDown(int selectedRow) {
> + int i = getRowCount();
> + back.moveDown(selectedRow);
> + fireTableRowsUpdated(i, i+1);
> + }
> +}
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,665 @@
> +/*
> + Copyright (C) 2013 Red Hat
> +
> + This program 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; either version 2 of the License, or
> + (at your option) any later version.
> +
> + This program 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 this program; if not, write to the Free Software
> + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +package net.sourceforge.jnlp.controlpanel;
> +
> +import java.awt.BorderLayout;
> +import java.io.BufferedWriter;
> +import java.io.File;
> +import java.io.FileOutputStream;
> +import java.io.OutputStreamWriter;
> +import java.text.DateFormat;
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.Date;
> +import java.util.List;
> +import java.util.regex.Pattern;
> +import javax.swing.event.ChangeEvent;
> +import javax.swing.event.ListSelectionEvent;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletAction;
> +import net.sourceforge.appletextendedsecurity.UrlRegEx;
> +import javax.swing.DefaultCellEditor;
> +import javax.swing.JComboBox;
> +import javax.swing.JFrame;
> +import javax.swing.JOptionPane;
> +import javax.swing.JPanel;
> +import javax.swing.JTable;
> +import javax.swing.JTextField;
> +import javax.swing.event.ChangeListener;
> +import javax.swing.event.ListSelectionListener;
> +import javax.swing.table.DefaultTableCellRenderer;
> +import javax.swing.table.DefaultTableModel;
> +import javax.swing.table.TableCellEditor;
> +import javax.swing.table.TableCellRenderer;
> +import javax.swing.table.TableModel;
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletActionEntry;
> +import
net.sourceforge.appletextendedsecurity.impl.UnsignedAppletActionStorageOperator;
> +import net.sourceforge.appletextendedsecurity.AppletSecurityLevel;
> +import net.sourceforge.jnlp.config.DeploymentConfiguration;
> +import net.sourceforge.jnlp.runtime.Translator;
> +
> +public class UnsignedAppletsTrustingListPanel extends
javax.swing.JPanel {
> +
> + private javax.swing.JButton jButton1;
> + private javax.swing.JButton jButton2;
> + private javax.swing.JButton jButton3;
> + private javax.swing.JButton jButton4;
> + private javax.swing.JButton jButton5;
> + private javax.swing.JButton jButton6;
> + private javax.swing.JButton jButton7;
> + private javax.swing.JButton jButton8;
> + private javax.swing.JCheckBox jCheckBox1;
> + private javax.swing.JCheckBox jCheckBox2;
> + private javax.swing.JComboBox jComboBox1;
> + private javax.swing.JComboBox jComboBox2;
> + private javax.swing.JLabel jLabel1;
> + private javax.swing.JLabel jLabel2;
> + private javax.swing.JScrollPane jScrollPane1;
> + private javax.swing.JTabbedPane jTabPane1;
> + private javax.swing.JTable jTable1;
> + private javax.swing.JScrollPane jScrollPane2;
> + private javax.swing.JTable jTable2;
> + private final UnsignedAppletActionStorageOperator customBackEnd;
> + private final UnsignedAppletActionStorageOperator globalBackEnd;
> + private final UnsignedAppletActionTableModel customModel;
> + private final UnsignedAppletActionTableModel globalModel;
> + private final DeploymentConfiguration conf;
> + private javax.swing.JTable currentTable;
> + private UnsignedAppletActionTableModel currentModel;
> + private String lastDoc;
> + private String lastCode;
> +
> +
> + /*
> + * for testing and playing
> + */
> + public static void main(String args[]) {
> + final String defaultDir = System.getProperty("user.home") +
"/Desktop/";
> + final String defaultFileName1 = "terrorList1";
> + final String defaultFileName2 = "terrorList2";
> + final String defaultFile1 = defaultDir + defaultFileName1;
> + final String defaultFile2 = defaultDir + defaultFileName2;
> + java.awt.EventQueue.invokeLater(new Runnable() {
> + @Override
> + public void run() {
> + try {
> + JFrame f = new JFrame();
> + f.setSize(700, 300);
> + f.setLayout(new BorderLayout());
> + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> + DeploymentConfiguration cc = new
DeploymentConfiguration();
> + cc.load();
> + File ff1 = new File(defaultFile1);
> + File ff2 = new File(defaultFile2);
> + f.add(new UnsignedAppletsTrustingListPanel(ff2,
ff1, cc));
> + f.setVisible(true);
> + } catch (Exception ex) {
> + ex.printStackTrace();
> + }
> + }
> + });
> + }
> +
> + public UnsignedAppletsTrustingListPanel(File globalSettings,
File customSettings, DeploymentConfiguration conf) {
> + customBackEnd = new
UnsignedAppletActionStorageOperator(customSettings);
> + globalBackEnd = new
UnsignedAppletActionStorageOperator(globalSettings);
> + customModel = new UnsignedAppletActionTableModel(customBackEnd);
> + globalModel = new UnsignedAppletActionTableModel(globalBackEnd);
> + initComponents();
> + this.conf = conf;
> + AppletSecurityLevel gs = AppletSecurityLevel.getDefault();
> + String s =
conf.getProperty(DeploymentConfiguration.KEY_SECURITY_LEVEL);
> + if (s != null) {
> + gs = AppletSecurityLevel.fromString(s);
> + }
> + jComboBox1.setSelectedItem(gs);
> + jTable1.getSelectionModel().addListSelectionListener(new
SingleSelectionListenerImpl(jTable1));
> + jTable2.getSelectionModel().addListSelectionListener(new
SingleSelectionListenerImpl(jTable2));
> + currentTable = jTable1;
> + currentModel = customModel;
> + setButtons((!currentModel.back.isReadOnly()));
> + }
> +
> + public String
appletItemsToCaption(List<UnsignedAppletActionEntry> ii, String caption) {
> + StringBuilder sb = new StringBuilder();
> + for (UnsignedAppletActionEntry i : ii) {
> + sb.append(appletItemToCaption(i, caption)).append("\n");
> + }
> + return sb.toString();
> + }
> +
> + public String appletItemToCaption(UnsignedAppletActionEntry i,
String caption) {
> + return Translator.R("APPEXTSECguiPanelAppletInfoHederPart1",
caption, i.getDocumentBase().getFilteredRegEx())
> + + "\n (" +
Translator.R("APPEXTSECguiPanelAppletInfoHederPart2",
i.getUnsignedAppletAction(),
DateFormat.getInstance().format(i.getTimeStamp()))
> + + "\n " +
Translator.R("APPEXTSECguiTableModelTableColumnDocumentBase") + ": " +
i.getDocumentBase().getFilteredRegEx()
> + + "\n " +
Translator.R("APPEXTSECguiTableModelTableColumnCodeBase") + ": " +
i.getCodeBase().getFilteredRegEx()
> + + "\n " +
Translator.R("APPEXTSECguiTableModelTableColumnMainClass") + ": " +
((i.getMainClass() == null) ? "" : i.getMainClass())
> + + "\n " +
Translator.R("APPEXTSECguiTableModelTableColumnArchives") + ": " +
UnsignedAppletActionEntry.createArchivesString(i.getArchives());
> + }
> +
> + public void removeSelectedFromTable(JTable table) {
> + int[] originalIndexes = table.getSelectedRows();
> + List<Integer> newIndexes = new
ArrayList<Integer>(originalIndexes.length);
> + for (int i = 0; i < originalIndexes.length; i++) {
> + //we need to remap values first
> + int modelRow =
table.convertRowIndexToModel(originalIndexes[i]);
> + newIndexes.add(modelRow);
> + }
> + //now to sort so we can incrementaly dec safely
> + Collections.sort(newIndexes);
> + if (jCheckBox1.isSelected()) {
> + String s =
Translator.R("APPEXTSECguiPanelConfirmDeletionOf", newIndexes.size()) +
": \n";
> + UnsignedAppletActionEntry[] items =
currentModel.back.toArray();
> + for (int i = 0; i < newIndexes.size(); i++) {
> + Integer integer = newIndexes.get(i);
> + s += appletItemToCaption(items[integer], " ") + "\n";
> + }
> + int a = JOptionPane.showConfirmDialog(this, s);
> + if (a != JOptionPane.OK_OPTION) {
> + return;
> + }
> + }
> + int sub = 0;
> + for (int i = 0; i < newIndexes.size(); i++) {
> + Integer integer = newIndexes.get(i);
> + currentModel.removeRow(integer.intValue() + sub);
> + sub--;
> + }
> + }
> +
> + public void removeAllItemsFromTable(JTable table,
UnsignedAppletActionTableModel model) {
> + table.clearSelection();
> +
> + if (jCheckBox1.isSelected()) {
> + UnsignedAppletActionEntry[] items = model.back.toArray();
> + String s =
Translator.R("APPEXTSECguiPanelConfirmDeletionOf", items.length) + ": \n";
> + for (int i = 0; i < items.length; i++) {
> + s += appletItemToCaption(items[i], " ") + "\n";
> + }
> + int a = JOptionPane.showConfirmDialog(this, s);
> + if (a != JOptionPane.OK_OPTION) {
> + return;
> + }
> + }
> + model.clear();
> + }
> +
> + private void initComponents() {
> +
> + jScrollPane1 = new javax.swing.JScrollPane();
> + jScrollPane2 = new javax.swing.JScrollPane();
> + jTable1 = createTbale(customModel);
> + jTable2 = createTbale(globalModel);
> + jButton1 = new javax.swing.JButton();
> + jComboBox1 = new JComboBox(new AppletSecurityLevel[]{
> + AppletSecurityLevel.DENY_ALL,
> + AppletSecurityLevel.DENY_UNSIGNED,
> + AppletSecurityLevel.ASK_UNSIGNED,
> + AppletSecurityLevel.ALLOW_UNSIGNED
> + });
> + jComboBox1.setSelectedItem(AppletSecurityLevel.getDefault());
> + jLabel2 = new javax.swing.JLabel();
> + jLabel1 = new javax.swing.JLabel();
> + jComboBox2 = new javax.swing.JComboBox();
> + jButton2 = new javax.swing.JButton();
> + jButton5 = new javax.swing.JButton();
> + jButton3 = new javax.swing.JButton();
> + jButton4 = new javax.swing.JButton();
> + jCheckBox1 = new javax.swing.JCheckBox();
> + jCheckBox2 = new javax.swing.JCheckBox();
> + jButton6 = new javax.swing.JButton();
> + jButton7 = new javax.swing.JButton();
> + jButton8 = new javax.swing.JButton();
> + jTabPane1 = new javax.swing.JTabbedPane();
> +
> + jScrollPane1.setViewportView(jTable1);
> +
> + jScrollPane2.setViewportView(jTable2);
> +
> + jButton1.setText(Translator.R("APPEXTSECguiPanelHelpButton"));
> + jButton1.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton1ActionPerformed(evt);
> + }
> + });
> +
> + jComboBox1.addActionListener(new
java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jComboBox1ActionPerformed(evt);
> + }
> + });
> +
> + jLabel2.setText(Translator.R("APPEXTSECguiPanelSecurityLevel"));
> +
> +
jLabel1.setText(Translator.R("APPEXTSECguiPanelGlobalBehaviourCaption"));
> +
> + jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new
String[]{
> + Translator.R("APPEXTSECguiPanelDeleteMenuSelected"),
> + Translator.R("APPEXTSECguiPanelDeleteMenuAllA"),
> + Translator.R("APPEXTSECguiPanelDeleteMenuAllN"),
> + Translator.R("APPEXTSECguiPanelDeleteMenuAlly"),
> + Translator.R("APPEXTSECguiPanelDeleteMenuAlln"),
> + Translator.R("APPEXTSECguiPanelDeleteMenuAllAll")}));
> +
> + jButton2.setText(Translator.R("APPEXTSECguiPanelDeleteButton"));
> + jButton2.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton2ActionPerformed(evt);
> + }
> + });
> +
> + jButton5.setText(Translator.R("APPEXTSECguiPanelTestUrlButton"));
> + jButton5.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton5ActionPerformed(evt);
> + }
> + });
> +
> + jButton3.setText(Translator.R("APPEXTSECguiPanelAddRowButton"));
> + jButton3.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton3ActionPerformed(evt);
> + }
> + });
> +
> + jButton4.setText(Translator.R("APPEXTSECguiPanelValidateTableButton"));
> + jButton4.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton4ActionPerformed(evt);
> + }
> + });
> +
> + jCheckBox1.setSelected(true);
> + jCheckBox1.setText(Translator.R("APPEXTSECguiPanelAskeforeActionBox"));
> +
> + jCheckBox2.setText(Translator.R("APPEXTSECguiPanelShowRegExesBox"));
> + jCheckBox2.addActionListener(new
java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jCheckBox2ActionPerformed(evt);
> + }
> + });
> +
> + jButton6.setText(Translator.R("APPEXTSECguiPanelInverSelection"));
> + jButton6.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton6ActionPerformed(evt);
> + }
> + });
> +
> + jButton7.setText(Translator.R("APPEXTSECguiPanelMoveRowUp"));
> + jButton7.setEnabled(false);
> + jButton7.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton7ActionPerformed(evt);
> + }
> + });
> +
> + jButton8.setText(Translator.R("APPEXTSECguiPanelMoveRowDown"));
> + jButton8.setEnabled(false);
> + jButton8.addActionListener(new java.awt.event.ActionListener() {
> + @Override
> + public void actionPerformed(java.awt.event.ActionEvent
evt) {
> + jButton8ActionPerformed(evt);
> + }
> + });
> +
> + javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(this);
> + this.setLayout(layout);
> + layout.setHorizontalGroup(
> +
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(jTabPane1,
javax.swing.GroupLayout.Alignment.LEADING,
javax.swing.GroupLayout.DEFAULT_SIZE, 583,
Short.MAX_VALUE).addComponent(jLabel1,
javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.LEADING,
layout.createSequentialGroup().addComponent(jLabel2).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jComboBox1,
0, 474,
Short.MAX_VALUE)).addGroup(javax.swing.GroupLayout.Alignment.LEADING,
layout.createSequentialGroup().addComponent(jButton3).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jButton4).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jButton5).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
94,
Short.MAX_VALUE).addComponent(jButton8).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jButton7)).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(jButton2).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jComboBox2,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jButton6)).addGroup(layout.createSequentialGroup().addComponent(jCheckBox1).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jCheckBox2))).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
93, Short.MAX_VALUE).addComponent(jButton1,
javax.swing.GroupLayout.PREFERRED_SIZE, 108,
javax.swing.GroupLayout.PREFERRED_SIZE))).addContainerGap()));
> + layout.setVerticalGroup(
> +
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jLabel1).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jLabel2).addComponent(jComboBox1,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false).addComponent(jButton2).addComponent(jComboBox2).addComponent(jButton6,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(jCheckBox1).addComponent(jCheckBox2))).addComponent(jButton1,
javax.swing.GroupLayout.PREFERRED_SIZE, 53,
javax.swing.GroupLayout.PREFERRED_SIZE)).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jTabPane1,
javax.swing.GroupLayout.DEFAULT_SIZE, 161,
Short.MAX_VALUE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(jButton3).addComponent(jButton4).addComponent(jButton5).addComponent(jButton7).addComponent(jButton8)).addContainerGap()));
> +
> + JPanel pane1 = new JPanel(new BorderLayout());
> + JPanel pane2 = new JPanel(new BorderLayout());
> + pane1.add(jScrollPane1);
> + pane2.add(jScrollPane2);
> + jTabPane1.add(pane1);
> + jTabPane1.add(pane2);
> + jTabPane1.setTitleAt(0,
Translator.R("APPEXTSECguiPanelCustomDefs"));
> + jTabPane1.setTitleAt(1,
Translator.R("APPEXTSECguiPanelGlobalDefs"));
> + jTabPane1.setToolTipTextAt(0,
DeploymentConfiguration.getAppletTrustCustomSettingsPath().getAbsolutePath());
> + jTabPane1.setToolTipTextAt(1,
DeploymentConfiguration.getAppletTrustGlobalSettingsPath().getAbsolutePath());
> + jTabPane1.addChangeListener(new ChangeListener() {
> + @Override
> + public void stateChanged(ChangeEvent e) {
> + switch (jTabPane1.getSelectedIndex()) {
> + case 0:
> + currentModel = customModel;
> + currentTable = jTable1;
> + break;
> + case 1:
> + currentModel = globalModel;
> + currentTable = jTable2;
> + break;
> + }
> + setButtons((!currentModel.back.isReadOnly()));
> + }
> + });
> + }
> +
> + private void
jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {
> + try {
> + conf.setProperty(DeploymentConfiguration.KEY_SECURITY_LEVEL,
((AppletSecurityLevel) jComboBox1.getSelectedItem()).toChars());
> + conf.save();
> + } catch (Exception ex) {
> + ex.printStackTrace();
> + JOptionPane.showMessageDialog(this, ex);
> + }
> + }
> +
> + private void jButton2ActionPerformed(java.awt.event.ActionEvent
evt) {
> +
> + if (jComboBox2.getSelectedIndex() == 0) {
> + removeSelectedFromTable(currentTable);
> + }
> + if (jComboBox2.getSelectedIndex() == 1) {
> + removeByBehaviour(UnsignedAppletAction.ALWAYS);
> + }
> + if (jComboBox2.getSelectedIndex() == 2) {
> + removeByBehaviour(UnsignedAppletAction.NEVER);
> + }
> + if (jComboBox2.getSelectedIndex() == 3) {
> + removeByBehaviour(UnsignedAppletAction.YES);
> + }
> + if (jComboBox2.getSelectedIndex() == 4) {
> + removeByBehaviour(UnsignedAppletAction.NO);
> + }
> + if (jComboBox2.getSelectedIndex() == 5) {
> + removeAllItemsFromTable(currentTable, customModel);
> + }
> + }
> +
> + private void jButton5ActionPerformed(java.awt.event.ActionEvent
evt) {
> +
> + String s1 =
JOptionPane.showInputDialog(Translator.R("APPEXTSECguiPanelDocTest"),
lastDoc);
> + String s2 =
JOptionPane.showInputDialog(Translator.R("APPEXTSECguiPanelCodeTest"),
lastCode);
> + lastDoc = s1;
> + lastCode = s2;
> + try {
> + List<UnsignedAppletActionEntry> i =
currentModel.back.getMatchingItems(s1, s2, null, null);
> + if (i == null || i.isEmpty()) {
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelNoMatch"));
> + } else {
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelMatchingNote") + "\n" +
appletItemsToCaption(i, Translator.R("APPEXTSECguiPanelMatched") + ": "));
> + }
> + } catch (Exception ex) {
> + ex.printStackTrace();
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelMatchingError", ex));
> + }
> +
> + }
> +
> + private void jButton3ActionPerformed(java.awt.event.ActionEvent
evt) {
> +
> + currentModel.addRow();
> + }
> +
> + private void jButton4ActionPerformed(java.awt.event.ActionEvent
evt) {
> +
> + File f = null;
> + try {
> + f = File.createTempFile("appletTable", "validation");
> + } catch (Exception ex) {
> + ex.printStackTrace();
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelCanNOtValidate", ex.toString()));
> + return;
> + }
> + try {
> + currentModel.back.writeContentsLocked();
> + BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
> + currentModel.back.writeContent(bw);
> + bw.flush();
> + bw.close();
> + UnsignedAppletActionStorageOperator copy = new
UnsignedAppletActionStorageOperator(f);
> + UnsignedAppletActionEntry[] items = copy.toArray();
> + for (int i = 0; i < items.length; i++) {
> + UnsignedAppletActionEntry unsignedAppletActionEntry
= items[i];
> + if (unsignedAppletActionEntry.getDocumentBase() !=
null &&
!unsignedAppletActionEntry.getDocumentBase().getRegEx().trim().isEmpty()) {
> + Pattern p =
Pattern.compile(unsignedAppletActionEntry.getDocumentBase().getRegEx());
> + p.matcher("someInput").find();
> + } else {
> + throw new
RuntimeException(Translator.R("APPEXTSECguiPanelEmptyDoc"));
> + }
> + if (unsignedAppletActionEntry.getCodeBase() != null
&& !unsignedAppletActionEntry.getCodeBase().getRegEx().trim().isEmpty()) {
> + Pattern p =
Pattern.compile(unsignedAppletActionEntry.getCodeBase().getRegEx());
> + p.matcher("someInput").find();
> + } else {
> + throw new
RuntimeException(Translator.R("APPEXTSECguiPanelEmptyCode"));
> + }
> +
UnsignedAppletActionEntry.createArchivesString(UnsignedAppletActionEntry.createArchivesList(UnsignedAppletActionEntry.createArchivesString(unsignedAppletActionEntry.getArchives())));
> +
> + }
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelTableValid"));
> + } catch (Exception ex) {
> + ex.printStackTrace();
> + JOptionPane.showMessageDialog(this,
Translator.R("APPEXTSECguiPanelTableInvalid ", ex.toString()));
> + } finally {
> + f.delete();
> + }
> +
> + }
> +
> + private void
jCheckBox2ActionPerformed(java.awt.event.ActionEvent evt) {
> +
> + reloadTable();
> + }
> +
> + private void jButton6ActionPerformed(java.awt.event.ActionEvent
evt) {
> + int[] selectedIndexs = currentTable.getSelectedRows();
> + currentTable.selectAll();
> +
> + for (int i = 0; i < currentTable.getRowCount(); i++) {
> + for (int selectedIndex : selectedIndexs) {
> + if (selectedIndex == i) {
> + currentTable.removeRowSelectionInterval(i, i);
> + break;
> + }
> + }
> + }
> + }
> +
> + private void jButton7ActionPerformed(java.awt.event.ActionEvent
evt) {
> + int orig = currentTable.getSelectedRow();
> + int i = currentTable.convertRowIndexToModel(orig);
> + currentModel.moveUp(i);
> + reloadTable();
> + if (orig >= 1) {
> + currentTable.getSelectionModel().setSelectionInterval(orig - 1,
orig - 1);
> + }
> + }
> +
> + private void jButton8ActionPerformed(java.awt.event.ActionEvent
evt) {
> + int orig = currentTable.getSelectedRow();
> + int i = currentTable.convertRowIndexToModel(orig);
> + currentModel.moveDown(i);
> + reloadTable();
> + if (orig < currentModel.getRowCount()) {
> + currentTable.getSelectionModel().setSelectionInterval(orig + 1,
orig + 1);
> + }
> + }
> +
> + private void jButton1ActionPerformed(java.awt.event.ActionEvent
evt) {
> + }
> +
> + private void setButtons(boolean b) {
> + jButton2.setEnabled(b);
> + jButton3.setEnabled(b);
> + jButton6.setEnabled(b);
> + jButton7.setEnabled(b);
> + jButton8.setEnabled(b);
> + }
> +
> + private JTable createTbale(final TableModel model) {
> + JTable jt = new JTable() {
> + @Override
> + public TableCellEditor getCellEditor(int row, int column) {
> + if (column == 0) {
> + return new DefaultCellEditor(new JComboBox(new
UnsignedAppletAction[]{UnsignedAppletAction.ALWAYS,
UnsignedAppletAction.NEVER, UnsignedAppletAction.YES,
UnsignedAppletAction.NO}));
> + }
> + if (column == 2) {
> + return new DefaultCellEditor(new
MyTextField((UrlRegEx) (model.getValueAt(row, column))));
> + }
> + if (column == 3) {
> + return new DefaultCellEditor(new
MyTextField((UrlRegEx) (model.getValueAt(row, column))));
> + }
> + return super.getCellEditor(row, column);
> + }
> +
> + @Override
> + public TableCellRenderer getCellRenderer(int row, int
column) {
> + if (column == 1) {
> + return new
UrlRegexCellRenderer.MyDateCellRenderer((Date) (model.getValueAt(row,
column)));
> + }
> + if (column == 2) {
> + if (!jCheckBox2.isSelected()) {
> + return new UrlRegexCellRenderer((UrlRegEx)
(model.getValueAt(row, column)));
> + }
> + }
> + if (column == 3) {
> + if (!jCheckBox2.isSelected()) {
> + return new UrlRegexCellRenderer((UrlRegEx)
(model.getValueAt(row, column)));
> + }
> + }
> + return super.getCellRenderer(row, column);
> + }
> + };
> + jt.setRowHeight(jt.getRowHeight() + jt.getRowHeight() / 2);
> + jt.setModel(model);
> + return jt;
> +
> + }
> +
> + private void reloadTable() {
> + currentTable.setModel(new DefaultTableModel());
> + currentTable.setModel(currentModel);
> +
> + }
> +
> + private void removeByBehaviour(UnsignedAppletAction
unsignedAppletAction) {
> + UnsignedAppletActionEntry[] items = currentModel.back.toArray();
> + if (jCheckBox1.isSelected()) {
> + List<UnsignedAppletActionEntry> toBeDeleted = new
ArrayList();
> + for (int i = 0; i < items.length; i++) {
> + UnsignedAppletActionEntry unsignedAppletActionEntry
= items[i];
> + if
(unsignedAppletActionEntry.getUnsignedAppletAction() ==
unsignedAppletAction) {
> + toBeDeleted.add(unsignedAppletActionEntry);
> + }
> +
> + }
> + String s =
Translator.R("APPEXTSECguiPanelConfirmDeletionOf",
toBeDeleted.size())+": \n";
> + for (int i = 0; i < toBeDeleted.size(); i++) {
> + s += appletItemToCaption(toBeDeleted.get(i), " ") +
"\n";
> + }
> + int a = JOptionPane.showConfirmDialog(this, s);
> + if (a != JOptionPane.OK_OPTION) {
> + return;
> + }
> + }
> + currentModel.removeByBehaviour(unsignedAppletAction);
> + }
> +
> + public static final class MyTextField extends JTextField {
> +
> + private final UrlRegEx keeper;
> +
> + private MyTextField(UrlRegEx urlRegEx) {
> + if (urlRegEx == null) {
> + keeper = new UrlRegEx("");
> + } else {
> + this.keeper = urlRegEx;
> + }
> + setText(keeper.getFilteredRegEx());
> + }
> +
> + @Override
> + public void setText(String t) {
> + super.setText(keeper.getRegEx());
> + }
> + }
> +
> + public static final class UrlRegexCellRenderer extends
DefaultTableCellRenderer {
> +
> + private final UrlRegEx keeper;
> +
> + private UrlRegexCellRenderer(UrlRegEx urlRegEx) {
> + if (urlRegEx == null) {
> + keeper = new UrlRegEx("");
> + } else {
> + this.keeper = urlRegEx;
> + }
> + setText(keeper.getFilteredRegEx());
> + }
> +
> + @Override
> + public void setText(String t) {
> + if (keeper == null) {
> + super.setText("");
> + } else {
> + super.setText(keeper.getFilteredRegEx());
> + }
> + }
> +
> + public static final class MyDateCellRenderer extends
DefaultTableCellRenderer {
> +
> + private final Date keeper;
> +
> + private MyDateCellRenderer(Date d) {
> + this.keeper = d;
> + setText(DateFormat.getInstance().format(d));
> + }
> +
> + @Override
> + public void setText(String t) {
> + if (keeper == null) {
> + super.setText("");
> + } else {
> + super.setText(DateFormat.getInstance().format(keeper));
> + }
> + }
> + }
> + }
> +
> + private class SingleSelectionListenerImpl implements
ListSelectionListener {
> +
> + private final JTable table;
> +
> + public SingleSelectionListenerImpl(JTable table) {
> + this.table = table;
> + }
> +
> + @Override
> + public void valueChanged(ListSelectionEvent e) {
> + if (table.getSelectedRows().length == 1) {
> + jButton7.setEnabled(true);
> + jButton8.setEnabled(true);
> + } else {
> + jButton7.setEnabled(false);
> + jButton8.setEnabled(false);
> + }
> + }
> + }
> +}
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/resources/Messages.properties
> --- a/netx/net/sourceforge/jnlp/resources/Messages.properties Thu
Jan 31 11:12:35 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties Fri
Feb 01 20:55:48 2013 +0100
> @@ -474,3 +474,57 @@
> SPLASHerrorInInformation = Error during loading of information
element, verify source rather
> SPLASHmissingInformation = Information element is missing, verify
source rather
> SPLASHchainWas = This is the list of exceptions that occurred
launching your applet. Please note, those exceptions can be from
multiple applets. For a good bug report, be sure to run only one applet.
> +
> +APPEXTSECappletSecurityLevelExtraHighId=Extra High Security
> +APPEXTSECappletSecurityLevelVeryHighId=Very High Security
> +APPEXTSECappletSecurityLevelHighId=High Security
> +APPEXTSECappletSecurityLevelLowId=Low Security
> +APPEXTSECappletSecurityLevelExtraHighExplanation=No applet will be run
> +APPEXTSECappletSecurityLevelVeryHighExplanation=No unsigned applets
will be run
> +APPEXTSECappletSecurityLevelHighExplanation=User will be prompted
for each unsigned applet
> +APPEXTSECappletSecurityLevelLowExplanation=All, even untrusted,
applets will be run
OK not typo but IMO s/ applets/ unsigned applets/
> +APPEXTSECunsignedAppletActionAlways=Always trust this applet(s)
OK again not typo but maybe s/this applet(s)/matching applets/
> +APPEXTSECunsignedAppletActionNever=Never trust this applet(s)
> +APPEXTSECunsignedAppletActionYes=This applet was visited and allowed
> +APPEXTSECunsignedAppletActionNo=This applet was visited and denied
> +APPEXTSECControlPanelExtendedAppletSecurityTitle=Extended applet
security
> +APPEXTSECguiTableModelTableColumnAction=Action
> +APPEXTSECguiTableModelTableColumnDateOfAction=Date of action
> +APPEXTSECguiTableModelTableColumnDocumentBase=Document-base
> +APPEXTSECguiTableModelTableColumnCodeBase=Code-base
> +APPEXTSECguiTableModelTableColumnMainClass=Main class
> +APPEXTSECguiTableModelTableColumnArchives=Archives
> +APPEXTSECguiPanelAppletInfoHederPart1={0} {1}
> +APPEXTSECguiPanelAppletInfoHederPart2={0} from {1}
> +APPEXTSECguiPanelConfirmDeletionOf=Are you sure you want to delete
following {0} items
> +APPEXTSECguiPanelHelpButton=Help
> +APPEXTSECguiPanelSecurityLevel=Security Level
> +APPEXTSECguiPanelGlobalBehaviourCaption=Settings of global behaviour
for applets
> +APPEXTSECguiPanelDeleteMenuSelected=selected
> +APPEXTSECguiPanelDeleteMenuAllA=all allowed (A)
> +APPEXTSECguiPanelDeleteMenuAllN=all forbidden (N)
> +APPEXTSECguiPanelDeleteMenuAlly=all approved (y)
> +APPEXTSECguiPanelDeleteMenuAlln=all disaprooved (n)
s/disaprooved/rejected/ :^)
> +APPEXTSECguiPanelDeleteMenuAllAll=absolute all
s/absolute all/all matches/ :^)
> +APPEXTSECguiPanelDeleteButton=Delete
> +APPEXTSECguiPanelTestUrlButton=Test url
> +APPEXTSECguiPanelAddRowButton=Add new row
> +APPEXTSECguiPanelValidateTableButton=Validate table
> +APPEXTSECguiPanelAskeforeActionBox=Ask me before action
> +APPEXTSECguiPanelShowRegExesBox=Show full regular expressions
> +APPEXTSECguiPanelInverSelection=Invert selection
> +APPEXTSECguiPanelMoveRowUp=Move row up
> +APPEXTSECguiPanelMoveRowDown=Move row down
> +APPEXTSECguiPanelCustomDefs=Custom definitions
> +APPEXTSECguiPanelGlobalDefs=Global definitions
> +APPEXTSECguiPanelDocTest=Type document base URL
> +APPEXTSECguiPanelCodeTest=Type code base URL
> +APPEXTSECguiPanelNoMatch=Nothing matched
> +APPEXTSECguiPanelMatchingNote=Please note, that only first matched
result will be considered as result.
> +APPEXTSECguiPanelMatched=Matched
> +APPEXTSECguiPanelMatchingError=Error during matching: {0}
> +APPEXTSECguiPanelCanNotValidate=Can not validate, can not create tmp
file - {0}
> +APPEXTSECguiPanelEmptyDoc=All document-bases must be full
> +APPEXTSECguiPanelEmptyCode=All code-bases must be full
> +APPEXTSECguiPanelTableValid=Table looks valid
> +APPEXTSECguiPanelTableInvalid=Invalid with following error: {0}
> \ No newline at end of file
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/util/lockingfile/LockingFile.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/util/lockingfile/LockingFile.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,156 @@
> +/*
> +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.util.lockingfile;
> +
> +import java.nio.channels.FileChannel;
> +
> +import java.io.RandomAccessFile;
> +
> +import java.io.File;
> +import java.io.IOException;
> +import java.nio.channels.FileLock;
> +import java.util.Map;
> +import java.util.WeakHashMap;
> +import java.util.concurrent.locks.ReentrantLock;
> +
> +/*
> + * Process & thread locked access to a file. Creates file if it does
not already exist.
> + */
> +public class LockingFile {
> +
> + // The file for access
> + private RandomAccessFile randomAccessFile;
> + private FileChannel fileChannel;
> + private File file;
> +
> + // A file lock will protect against locks for multiple
> + // processes, while a thread lock is still needed within a
single JVM.
> +
> + private FileLock processLock = null;
> + private ReentrantLock threadLock = new ReentrantLock();
> + private boolean readOnly;
> +
> + private LockingFile(File file) {
> + this.file = file;
> + try{
> + //just try to ctreate
> + this.file.createNewFile();
> + }catch(Exception ex){
> + //intentionaly silent
> + }
> + if (!this.file.isFile() && file.getParentFile()!=null &&
!file.getParentFile().canWrite() ){
> + readOnly=true;
> + } else{
> + this.readOnly = !file.canWrite();
> + if (!readOnly && file.getParentFile()!=null &&
!file.getParentFile().canWrite()){
> + readOnly=true;
> + }
> + }
> + }
> +
> + public boolean isReadOnly() {
> + return readOnly;
> + }
> +
> +
> +
> + // Provide shared access to LockedFile's via weak map
> + static private final Map<File, LockingFile> instanceCache = new
WeakHashMap<File, LockingFile>();
> +
> + /**
> + * Get a LockingFile for a given File.
> + * Ensures that we share the same instance for all threads
> + * @param file the file to lock
> + * @return a LockingFile instance
> + */
> + synchronized public static LockingFile getInstance(File file) {
> + if (!instanceCache.containsKey(file)) {
> + instanceCache.put(file, new LockingFile(file));
> + }
> +
> + return instanceCache.get(file);
> + }
> +
> + /**
> + * Get the file being locked.
> + *
> + * @return the file
> + */
> + public File getFile() {
> + return file;
> + }
> +
> + /**
> + * Lock access to the file. Lock is reentrant.
> + */
> + public void lock() throws IOException {
> + // Create if does not already exist, cannot lock
non-existing file
> + if (!readOnly){
> + this.file.createNewFile();
> + }
> +
> + this.threadLock.lock();
> + String rw="rws";
> + if (isReadOnly()){
> + rw="r";
> + }
> + if (file.exists()){
> + this.randomAccessFile = new RandomAccessFile(this.file, rw);
> + this.fileChannel = randomAccessFile.getChannel();
> + }
> +
> + if (!isReadOnly()) this.processLock = this.fileChannel.lock();
> + }
> +
> + /**
> + * Unlock access to the file. Lock is reentrant.
> + */
> + public void unlock() throws IOException {
> + boolean releaseProcessLock = (this.threadLock.getHoldCount()
== 1);
> + try {
> + if (releaseProcessLock && this.processLock != null) {
> + this.processLock.release();
> + this.randomAccessFile.close();
> + this.fileChannel.close();
> + }
> + } finally {
> + this.processLock = null;
> + }
> + this.threadLock.unlock();
> + }
> +}
> \ No newline at end of file
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/util/lockingfile/LockingReaderWriter.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/jnlp/util/lockingfile/LockingReaderWriter.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,201 @@
> +/*
> +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.util.lockingfile;
> +
> +import java.io.BufferedWriter;
> +
> +import java.io.BufferedReader;
> +import java.io.File;
> +import java.io.FileInputStream;
> +import java.io.FileOutputStream;
> +import java.io.IOException;
> +import java.io.InputStreamReader;
> +import java.io.OutputStreamWriter;
> +
> +/**
> + * Process-locked string storage backed by a file.
> + * Each string is stored on its own line.
> + * Any new-lines must be encoded somehow if they are to be stored.
> + */
> +public abstract class LockingReaderWriter {
> +
> + private LockingFile lockedFile;
> +
> + /**
> + * Create locking file-backed storage.
> + * @param file the storage file
> + */
> + public LockingReaderWriter(File file) {
> + this.lockedFile = LockingFile.getInstance(file);
> + }
> +
> + /**
> + * Get the underlying file.
> + * Any access to this file should use lock() & unlock().
> + *
> + * @return the file
> + */
> + public File getBackingFile() {
> + return this.lockedFile.getFile();
> + }
> +
> + public boolean isReadOnly() {
> + return this.lockedFile.isReadOnly();
> + }
> +
> + /**
> + * Lock the underlying storage. Lock is reentrant.
> + */
> + public void lock() {
> + try {
> + lockedFile.lock();
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + }
> + }
> +
> + /**
> + * Unlock the underlying storage. Lock is reentrant.
> + */
> + public void unlock() {
> + try {
> + lockedFile.unlock();
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + }
> + }
> +
> + /**
> + * Writes stored contents to file. Assumes lock is held.
> + * @throws IOException
> + */
> + protected void writeContents() throws IOException {
> + if (!getBackingFile().isFile()){
> + return;
> + }
> + if (isReadOnly()){
> + return;
> + }
> + BufferedWriter writer = null;
> + try {
> + writer = new BufferedWriter(new OutputStreamWriter(
> + new FileOutputStream(getBackingFile()), "UTF-8"));
> + writeContent(writer);
> + writer.flush();
> + } finally {
> + if (writer != null) {
> + writer.close();
> + }
> + }
> + }
> +
> + protected abstract void writeContent(BufferedWriter writer)
throws IOException;
> +
> + /**
> + * Reads contents from file. Assumes lock is held.
> + * @throws IOException
> + */
> + protected void readContents() throws IOException {
> + if (!getBackingFile().isFile()){
> + return;
> + }
> + BufferedReader reader = null;
> + try {
> + reader = new BufferedReader(new InputStreamReader(
> + new FileInputStream(getBackingFile()), "UTF-8"));
> +
> + while (true) {
> + String line = reader.readLine();
> + if (line == null) {
> + break;
> + }
> + readLine(line);
> + }
> + } finally {
> + if (reader != null) {
> + reader.close();
> + }
> + }
> + }
> +
> + /**
> + * Reads contents from file. creating is lock .
I have already proofread this !
'Reads contents from the file, first acquring a lock.'
> + * @throws IOException
> + */
> + protected synchronized void readContentsLocked() throws
IOException {
> + doLocked(new Runnable() {
> +
> + @Override
> + public void run() {
> + try {
> + readContents();
> + } catch (IOException ex) {
> + throw new StorageIoException(ex);
> + }
> + }
> + });
> + }
> +
> + /**
> + * Reads contents from file. creating is lock .
'Write contents to the file, first acquring a lock.'
> + * @throws IOException
> + */
> + protected synchronized void writeContentsLocked() throws
IOException {
> + doLocked(new Runnable() {
> +
> + public void run() {
> + try {
> + writeContents();
> + } catch (IOException ex) {
> + throw new StorageIoException(ex);
> + }
> + }
> + });
> +
> + }
> +
> + protected void doLocked(Runnable r) {
> + lock();
> + try {
> + r.run();
> + } finally {
> + unlock();
> + }
> + }
> +
> + protected abstract void readLine(String line);
> +}
> diff -r e631770d76ba
netx/net/sourceforge/jnlp/util/lockingfile/StorageIoException.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/netx/net/sourceforge/jnlp/util/lockingfile/StorageIoException.java Fri
Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,22 @@
> +package net.sourceforge.jnlp.util.lockingfile;
> +
> +/**
> + * Thrown when an exception occurs using the storage (namely
IOException)
> + */
> +public class StorageIoException extends RuntimeException {
> +
> + LockingReaderWriter outer;
> +
> + public StorageIoException(Exception e) {
> + super(e);
> + }
> +
> + public StorageIoException(String e) {
> + super(e);
> + }
> +
> + public StorageIoException(Exception e, LockingReaderWriter outer) {
> + super(e);
> + this.outer = outer;
> + }
> +}
> diff -r e631770d76ba
tests/netx/unit/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/tests/netx/unit/net/sourceforge/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,97 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.appletextendedsecurity.impl;
> +
> +import net.sourceforge.appletextendedsecurity.UnsignedAppletActionEntry;
> +import java.io.File;
> +import java.io.IOException;
> +import java.util.Arrays;
> +import net.sourceforge.jnlp.ServerAccess;
> +import org.junit.Assert;
> +import org.junit.BeforeClass;
> +import org.junit.Test;
> +
> +public class UnsignedAppletActionStorageImplTest {
> +
> + private static File f1;
> + private static File f2;
> + private static File f3;
> + private static File f4;
> +
> + @BeforeClass
> + public static void preapreTestFiles() throws IOException {
> + f1 = File.createTempFile("itwMatching", "testFile1");
> + f2 = File.createTempFile("itwMatching", "testFile2");
> + f3 = File.createTempFile("itwMatching", "testFile3");
> + f4 = File.createTempFile("itwMatching", "testFile4");
> + ServerAccess.saveFile("A 123456 .* .* main jar1;jar2", f1);
> + ServerAccess.saveFile("A 123456 .* \\Qbla\\E main
jar1;jar2", f2);
> + }
> +
> + @Test
> + public void allMatchingDocAndCode() {
> + UnsignedAppletActionStorageImpl i1 = new
UnsignedAppletActionStorageImpl(f1);
> + UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla",
"blaBla", "main", Arrays.asList(new String[]{"jar1", "jar2"}));
> + Assert.assertNotNull("r1 should be found", r1);
> + UnsignedAppletActionEntry r3 = i1.getMatchingItem("blah",
"blaBla", "main", Arrays.asList(new String[]{"jar2", "jar1"}));
> + Assert.assertNotNull("r3 should be found", r1);
> + UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla",
"blaBlam", "wrong_main", Arrays.asList(new String[]{"jar1", "jar2"}));
> + Assert.assertNull("r2 should NOT be found", r2);
> + UnsignedAppletActionEntry r4 = i1.getMatchingItem("blha",
"blaBlam", "main", Arrays.asList(new String[]{"jar2", "wrong_jar"}));
> + Assert.assertNull("r4 should NOT be found", r4);
> + UnsignedAppletActionEntry r5 = i1.getMatchingItem("blaBla",
"blaBlaBla", "main", Arrays.asList(new String[]{"jar2"}));
> + Assert.assertNull("r5 should NOT be found", r5);
> +
> + }
> +
> + @Test
> + public void allMatchingDocAndStrictCode() {
> + UnsignedAppletActionStorageImpl i1 = new
UnsignedAppletActionStorageImpl(f2);
> + UnsignedAppletActionEntry r1 =
i1.getMatchingItem("whatever", "bla", "main", Arrays.asList(new
String[]{"jar1", "jar2"}));
> + Assert.assertNotNull("r1 should be found", r1);
> + UnsignedAppletActionEntry r3 =
i1.getMatchingItem("whatever", null, "main", Arrays.asList(new
String[]{"jar2", "jar1"}));
> + Assert.assertNotNull("r3 should be found", r1);
> + UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla",
"blaBlam", "main", Arrays.asList(new String[]{"jar1", "jar2"}));
> + Assert.assertNull("r2 should NOT be found", r2);
> + UnsignedAppletActionEntry r4 = i1.getMatchingItem(null,
"blaBlam", null, null);
> + Assert.assertNull("r4 should NOT be found", r4);
> +
> + }
> +
> + @Test
> + public void allMatchingDocAndCodeWithNulls() {
> + UnsignedAppletActionStorageImpl i1 = new
UnsignedAppletActionStorageImpl(f1);
> + UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla",
"blaBla", null, null);
> + Assert.assertNotNull("r1 should be found", r1);
> + UnsignedAppletActionEntry r3 = i1.getMatchingItem("bla",
"whatever", "", null);
> + Assert.assertNotNull("r3 should be found", r1);
> + UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla",
"blaBla", null, Arrays.asList(new String[]{"jar2", "jar1"}));
> + Assert.assertNotNull("r2 should be found", r2);
> + UnsignedAppletActionEntry r4 = i1.getMatchingItem("bla",
"blaBla", "main", null);
> + Assert.assertNotNull("r4 should be found", r4);
> + UnsignedAppletActionEntry r5 = i1.getMatchingItem("",
"blaBla", "main", Arrays.asList(new String[]{"jar2", "jar1"}));
> + Assert.assertNotNull("r5 should be found", r5);
> + UnsignedAppletActionEntry r6 = i1.getMatchingItem(null,
null, "main", Arrays.asList(new String[]{"jar2", "jar1"}));
> + Assert.assertNotNull("r6 should be found", r6);
> + UnsignedAppletActionEntry r7 = i1.getMatchingItem(null,
null, "main", Arrays.asList(new String[]{"jar2", "jar11"}));
> + Assert.assertNull("r7 should NOT be found", r7);
> +
> +
> + }
> +}
> diff -r e631770d76ba
tests/netx/unit/net/sourceforge/jnlp/util/lockingfile/LockingStringListStorageTest.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
b/tests/netx/unit/net/sourceforge/jnlp/util/lockingfile/LockingStringListStorageTest.java
Fri Feb 01 20:55:48 2013 +0100
> @@ -0,0 +1,385 @@
> +/*
> +Copyright (C) 2013 Red Hat
> +
> +This program 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; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program 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 this program; if not, write to the Free Software
> +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +*/
> +
> +package net.sourceforge.jnlp.util.lockingfile;
> +
> +import static org.junit.Assert.assertFalse;
> +import static org.junit.Assert.assertTrue;
> +import org.junit.Before;
> +import java.io.BufferedWriter;
> +import java.io.File;
> +import java.io.IOException;
> +import java.util.ArrayList;
> +import java.util.List;
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +
> +
> +public class LockingStringListStorageTest {
> +
> +/**
> + * Process-locked string storage backed by a file.
> + * Each string is stored on its own line.
> + * Any new-lines must be encoded somehow if they are to be stored.
> + */
> +public static class LockingStringListStorage extends
LockingReaderWriter {
> +
> + private List<String> cachedContents = new ArrayList<String>();
> +
> + //To sutisfy testengine, void constructor and dummy testmethod
> + public LockingStringListStorage() throws IOException {
> + this(createTmpBackend());
> + }
> +
> + @Test
> + public void lockingStringListStorageCanBeInstantiated(){
> + Assert.assertNotNull(this);
> + }
> +
> +
> + private static File createTmpBackend() throws IOException{
> + File f = File.createTempFile("forTests","emptyConstructor");
> + f.deleteOnExit();
> + return f;
> + }
> +
> +
> + /**
> + * Create locking file-backed storage.
> + * @param file the storage file
> + */
> + public LockingStringListStorage(File file) {
> + super(file);
> + }
> +
> + /**
> + * Get the underlying string list cache. Should lock
> + * before using.
> + * @return the cache
> + */
> + final protected List<String> getCachedContents() {
> + return cachedContents;
> + }
> +
> + @Override
> + public void writeContent(BufferedWriter writer) throws IOException {
> + for (String string : cachedContents) {
> + writer.write(string);
> + writer.newLine();
> + }
> + }
> +
> + @Override
> + protected void readLine(String line) {
> + this.cachedContents.add(line);
> + }
> +
> + @Override
> + protected void readContents() throws IOException {
> + cachedContents.clear();
> + super.readContents();
> + }
> +
> + /*
> + * Atomic container abstraction methods. These all allow the
file-backed
> + * string list to be treated as a convenient in-memory object.
> + */
> + /**
> + * Appends the specified line to the end of the storage.
> + *
> + * @param line the line to add
> + */
> + synchronized public void add(final String line) {
> + doLocked(new Runnable() {
> +
> + public void run() {
> + try {
> + readContents();
> + cachedContents.add(line);
> + writeContents();
> + } catch (IOException ex) {
> + throw new StorageIoException(ex);
> + }
> + }
> + });
> + }
> +
> + /**
> + * Returns an array containing all of the lines in the storage.
> + *
> + * @return an array of the stored strings
> + */
> + synchronized public String[] toArray() {
> + lock();
> + try {
> + readContents();
> + return cachedContents.toArray(new String[]{});
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Returns amount of lines in the storage.
> + *
> + * @return amount of stored strings
> + */
> + synchronized public int size() {
> + lock();
> + try {
> + readContents();
> + return cachedContents.size();
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Returns 'i'th line
> + *
> + * @return the line
> + */
> + synchronized public String get(int i) {
> + lock();
> + try {
> + readContents();
> + return cachedContents.get(i);
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Set the 'i'th line
> + *
> + * @param line the new line
> + */
> + synchronized public String set(int i, String line) {
> + lock();
> + try {
> + readContents();
> + return cachedContents.set(i, line);
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Returns a copied list containing all of the lines in the storage.
> + *
> + * @return a list of the stored strings
> + */
> + synchronized public List<String> toList() {
> + lock();
> + try {
> + readContents();
> + return new ArrayList<String>(cachedContents);
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Returns <tt>true</tt> if the storage contains the specified
element.
> + *
> + * @param line
> + * @return <tt>true</tt> if the storage contains the line
> + */
> + synchronized public boolean contains(String line) {
> + lock();
> + try {
> + readContents();
> + return cachedContents.contains(line);
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Empty the storage.
> + */
> + synchronized public void clear() {
> + lock();
> + try {
> + cachedContents.clear();
> + writeContents();
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> + }
> +
> + /**
> + * Removes the first occurrence of the specified element from
this list,
> + * if it is present (optional operation). If this list does not
contain
> + * the element, it is unchanged.
> + *
> + * @param line string to be removed from this list, if present
> + * @return <tt>true</tt> if the storage contained the line
> + */
> + synchronized public boolean remove(String line) {
> + boolean didRemove;
> +
> + lock();
> + try {
> + readContents();
> + didRemove = cachedContents.remove(line);
> + writeContents();
> + } catch (IOException e) {
> + throw new StorageIoException(e);
> + } finally {
> + unlock();
> + }
> +
> + return didRemove;
> + }
> +}
> +
> +
> + private static File storagefile;
> +
> + private static LockingStringListStorage newInstance() {
> + return new LockingStringListStorage(storagefile);
> + }
> +
> + @Before
> + public void setUp() throws IOException {
> + storagefile = File.createTempFile("foo", "bar");
> + }
> +
> + @Test
> + public void testSimpleActions() throws IOException {
> + LockingStringListStorage storage = newInstance();
> +
> + storage.add("teststring");
> + assertTrue(storage.contains("teststring"));
> + storage.remove("teststring");
> + assertFalse(storage.contains("teststring"));
> + }
> +
> + @Test
> + public void testInterleavedActions() throws IOException {
> + LockingStringListStorage storage1 = newInstance();
> + LockingStringListStorage storage2 = newInstance();
> +
> + storage1.add("teststring");
> + assertTrue(storage2.contains("teststring"));
> + storage2.remove("teststring");
> + assertFalse(storage1.contains("teststring"));
> + }
> +
> + static class TestThread extends Thread {
> + String testString;
> + int iterations;
> + Throwable error = null;
> +
> + TestThread(String testString, int iterations) {
> + this.testString = testString;
> + this.iterations = iterations;
> + }
> +
> + @Override
> + public void run() {
> + try {
> + LockingStringListStorage storage = newInstance();
> + for (int i = 0; i < iterations; i++) {
> + assertTrue(storage.contains(this.testString));
> + storage.add(this.testString);
> + storage.remove(this.testString);
> + assertTrue(storage.contains(this.testString));
> + }
> + } catch (Throwable error) {
> + error.printStackTrace();
> + this.error = error;
> + }
> + }
> + }
> +
> + private void concurrentReadWrites(int threadAmount, int iterations,
> + String testString) throws InterruptedException {
> + LockingStringListStorage storage = newInstance();
> +
> + storage.add(testString);
> +
> + List<TestThread> testThreads = new ArrayList<TestThread>();
> +
> + for (int i = 0; i < threadAmount; i++) {
> + TestThread thread = new TestThread(testString, iterations);
> + testThreads.add(thread);
> + thread.start();
> + }
> +
> + for (int i = 0; i < threadAmount; i++) {
> + testThreads.get(i).join();
> + }
> +
> + assertTrue(storage.contains(testString));
> + storage.remove(testString);
> +
> + // So long as number adds == number writes, we should be
left with
> + // nothing at end.
> + assertFalse(storage.contains(testString));
> + }
> +
> + // Long testing string, the contents are not important
> + private String makeLongTestString() {
> + StringBuilder sb = new StringBuilder();
> + for (int i = 0; i < 1000; i++) {
> + sb.append(Integer.toString(i));
> + }
> + return sb.toString();
> + }
> +
> + @Test
> + public void testManyReadWrite() throws Exception {
> + int oneThread = 1;
> + String shortString = "teststring";
> +
> + // This was causing 'too many open files' because
FileUtils#getFileLock
> + // leaks file descriptors. No longer used.
> + concurrentReadWrites(oneThread, 500 /* iterations */,
> + shortString);
> + }
> +
> + @Test
> + public void testManyThreads() throws Exception {
> + int threadAmount = 25;
> + String shortString = "teststring";
> + String longString = makeLongTestString();
> +
> + concurrentReadWrites(threadAmount, 10 /* per-thread
iterations */,
> + shortString);
> + concurrentReadWrites(threadAmount, 2 /* per-thread
iterations */,
> + longString);
> + }
> +
> +}
Happy hacking,
-Adam
More information about the distro-pkg-dev
mailing list