[rfc][icedtea-web] multiple remember actions

Jiri Vanek jvanek at redhat.com
Thu Apr 24 08:36:39 UTC 2014


Hi!

Based on previous two enhancements - [rfc][icedtea-web] replace jlabel by  jeditorpane and  Re: 
[rfc][icedtea-web] conditional disabling of manifes tattributes

this is enabling to save matching alaca action
  - benefits: one file, one  lock , one id, one table, one metadata and unlimited number of actions
  - drawbacks - suspiciously simply, maybe not so transparent, once more columns will be added, new 
editing

The patch grown due to changed signatures of methods. I will try to summarize:


* netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java"
  - original columnrnemaed to "Unsigned applet action" added "Library action" column
  - the value of those two columns is get from source.getAppletSecurityActions().* methods

* netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java
  - adapted "toString" method
  - added unset to list of combobox values for first two columns cell editors
  - filter of  "byValue" are now selecting via *or* - if any of action have the desired value, then 
it is true


* netx/net/sourceforge/jnlp/resources/Messages.properties"
  - enabled date in SUnsignedAllowedBefore and SUnsignedRejectedBefore  - thsi was actualy doone in 
ocde. I do not know why this was forgotten)
  - removed SAppletTitle - it was nasty :)
  - added nnew name of column 1 and new name fornew column 2

* netx/net/sourceforge/jnlp/resources/Messages_cs.properties
  also removed  SAppletTitle

* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
  - added stup for return of international date (jnlpruntime is holding the locales, thats why it 
its here)


  * netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
  -  showMatchingALACAttributePanel is receiving whole file (for purposes of reuse in reusable 
dialogue)) instead of just file.title

* netx/net/sourceforge/jnlp/security/SecurityDialogs.java few minor warning-clean up which I could 
not look onto.
  - showMatchingALACAttributePanel - to get file instead file.title and adapted to new  dialogue
   - checking action for always/never
   - using text for yes/no
   - getting response
   - storing response

* netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java
   - allowed public access via set(int id) and get(int id) - needed for generalization

* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java
   - changed signatures of :
   ExecuteAppletAction getUnsignedAppletAction() ->   AppletSecurityActions getAppletSecurityActions()
  - and
  setUnsignedAppletAction(ExecuteAppletAction unsignedAppletAction) -> 
etAppletSecurityActions(AppletSecurityActions actions)


* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java
  - added ID parameter to
   getMatchingItem
   getMatchingItemByDocumentBase
   getMatchingItemByCodeBase
   getMatchingItemByBases
  - this is a bit unhappy. But th e mechanism needs to find strong value first. So it mus know 
whichone it is looking fr :( so we cannot jsut return Actions and select later )

* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java
  - get and forward  the ID parameter
  - separated get action and get entry logic
  - one bug fix - when somebody  have visited applet, and have not clicked remember, and later he 
selected remember for codebase, then the "codebase" change never propagated. Now it does.
  - forwarding correct id into depth


* 
netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java
  - used the *or* action as in table
  - made aware of columns abstraction

* netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java
  - again propagated ID

* netx/net/sourceforge/jnlp/security/dialogs/MatchingALACAttributePanel.java
  - moved to new impl into apptrustwarningpanel  with other  similar panels

* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java:
  - added shower for MatchingAlaca

* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java
  - added pluginbridge back - maybe best to o here is to abstract getTitle() into jnlpfile. But as 
naother work...

* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/MatchingALACAttributePanel.java:
  - actual extension of AppTrustWarningPanel for matching alaca
  - getAppletTitle is emty, as it is handle in plain text

* 
netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java
  - removed duplicate code of getAppletTitle
  - shown the date of action

* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningDialog.java
  - removed - this is actually bug. It should be removed when generalized "remember" dialogue came in


* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningPanel.java
  - shown the date of action


* 
tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java
  - tests adapted to new ID style
  - well righ now I realised the high-level of tests of new logic are missing (I added the test 
datat but forgot to add also testcases ) - well wil be added in next round


Thanx!

J.
-------------- next part --------------
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java
--- a/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletActionTableModel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -48,7 +48,8 @@
 public class UnsignedAppletActionTableModel extends AbstractTableModel {
 
     final UnsignedAppletActionStorageExtendedImpl back;
-    private final String[] columns = new String[]{Translator.R("APPEXTSECguiTableModelTableColumnAction"),
+    private final String[] columns = new String[]{Translator.R("APPEXTSECguiTableModelTableColumnActionUB"),
+        Translator.R("APPEXTSECguiTableModelTableColumnActionMatchALACA"),
         Translator.R("APPEXTSECguiTableModelTableColumnDateOfAction"),
         Translator.R("APPEXTSECguiTableModelTableColumnDocumentBase"),
         Translator.R("APPEXTSECguiTableModelTableColumnCodeBase"),
@@ -79,21 +80,21 @@
             return AppletSecurityActions.class;
         }
         if (columnIndex == 1) {
-            return Date.class;
+            return AppletSecurityActions.class;
         }
         if (columnIndex == 2) {
-            return UrlRegEx.class;
+            return Date.class;
         }
         if (columnIndex == 3) {
             return UrlRegEx.class;
         }
         if (columnIndex == 4) {
-            return String.class;
+            return UrlRegEx.class;
         }
         if (columnIndex == 5) {
             return String.class;
         }
-        return Object.class;
+         return Object.class;
     }
 
     @Override
@@ -101,7 +102,7 @@
         if (back.isReadOnly()) {
             return false;
         }
-        if (columnIndex == 1) {
+        if (columnIndex == 2) {
             return false;
         }
         if (columnIndex == 0) {
@@ -118,18 +119,22 @@
 
         UnsignedAppletActionEntry source = back.toArray()[rowIndex];
         if (columnIndex == 0) {
-            return source.getUnsignedAppletAction();
+            return source.getAppletSecurityActions().getUnsignedAppletAction();
         }
         if (columnIndex == 1) {
+            return source.getAppletSecurityActions().getMatchingAlacaAction();
+        }
+
+        if (columnIndex == 2) {
             return source.getTimeStamp();
         }
-        if (columnIndex == 2) {
+        if (columnIndex == 3) {
             return source.getDocumentBase();
         }
-        if (columnIndex == 3) {
+        if (columnIndex == 4) {
             return source.getCodeBase();
         }
-        if (columnIndex == 4) {
+        if (columnIndex == 5) {
             return UnsignedAppletActionEntry.createArchivesString(source.getArchives());
         }
         return null;
@@ -146,7 +151,7 @@
         int i = getRowCount()-1;
         String s = "\\Qhttp://localhost:80/\\E.*";
         back.add(new UnsignedAppletActionEntry(
-                AppletSecurityActions.fromAction(ExecuteAppletAction.NEVER),
+                AppletSecurityActions.createDefault(),
                 new Date(),
                 new UrlRegEx(s),
                 new UrlRegEx(s),
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java
--- a/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/controlpanel/UnsignedAppletsTrustingListPanel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -76,6 +76,7 @@
 
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.Translator;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExtendedAppletSecurityHelp;
@@ -187,7 +188,7 @@
 
     public static 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("APPEXTSECguiPanelAppletInfoHederPart2", i.getAppletSecurityActions().toString(), DateFormat.getInstance().format(i.getTimeStamp()))
                 + "\n    " + Translator.R("APPEXTSECguiTableModelTableColumnDocumentBase") + ": " + i.getDocumentBase().getFilteredRegEx()
                 + "\n    " + Translator.R("APPEXTSECguiTableModelTableColumnCodeBase") + ": " + i.getCodeBase().getFilteredRegEx()
                 + "\n    " + Translator.R("APPEXTSECguiTableModelTableColumnArchives") + ": " + UnsignedAppletActionEntry.createArchivesString(i.getArchives());
@@ -702,19 +703,20 @@
             @Override
             public TableCellEditor getCellEditor(int row, int column) {
                 int columnx = convertColumnIndexToModel(column);
-                if (columnx == 0) {
+                if (columnx == 0 || columnx == 1) {
                     return new DefaultCellEditor(new JComboBox<>(new ExecuteAppletAction[] {
                             ExecuteAppletAction.ALWAYS,
                             ExecuteAppletAction.NEVER,
                             ExecuteAppletAction.YES,
-                            ExecuteAppletAction.NO }));
+                            ExecuteAppletAction.NO,
+                            ExecuteAppletAction.UNSET }));
                 }
-                if (columnx == 2) {
+                if (columnx == 3) {
                     column = convertColumnIndexToModel(column);
                     row = convertRowIndexToModel(row);
                     return new DefaultCellEditor(new MyTextField((UrlRegEx) (model.getValueAt(row, column))));
                 }
-                if (columnx == 3) {
+                if (columnx == 4) {
                     column = convertColumnIndexToModel(column);
                     row = convertRowIndexToModel(row);
                     return new DefaultCellEditor(new MyTextField((UrlRegEx) (model.getValueAt(row, column))));
@@ -725,19 +727,19 @@
             @Override
             public TableCellRenderer getCellRenderer(int row, int column) {
                 int columnx = convertColumnIndexToModel(column);
-                if (columnx == 1) {
+                if (columnx == 2) {
                     column = convertColumnIndexToModel(column);
                     row = convertRowIndexToModel(row);
                     return new UrlRegexCellRenderer.MyDateCellRenderer((Date) (model.getValueAt(row, column)));
                 }
-                if (columnx == 2) {
+                if (columnx == 3) {
                     if (!filterRegexesCheckBox.isSelected()) {
                         column = convertColumnIndexToModel(column);
                         row = convertRowIndexToModel(row);
                         return new UrlRegexCellRenderer((UrlRegEx) (model.getValueAt(row, column)));
                     }
                 }
-                if (columnx == 3) {
+                if (columnx == 4) {
                     if (!filterRegexesCheckBox.isSelected()) {
                         column = convertColumnIndexToModel(column);
                         row = convertRowIndexToModel(row);
@@ -768,16 +770,18 @@
         UnsignedAppletActionEntry[] items = currentModel.back.toArray();
         if (askBeforeActionCheckBox.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);
+            for (UnsignedAppletActionEntry unsignedAppletActionEntry : items) {
+                AppletSecurityActions actions = unsignedAppletActionEntry.getAppletSecurityActions();
+                 for (int j = 0; j < actions.getRealCount(); j++) {
+                    ExecuteAppletAction action = actions.getAction(j);
+                    if (action == 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";
+            for (UnsignedAppletActionEntry toBeDeleted1 : toBeDeleted) {
+                s += appletItemToCaption(toBeDeleted1, "  ") + "\n";
             }
             int a = JOptionPane.showConfirmDialog(this, s);
             if (a != JOptionPane.OK_OPTION) {
@@ -910,56 +914,81 @@
 
             @Override
             public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.ALWAYS) || o.equals(ExecuteAppletAction.NEVER));
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.ALWAYS) || o.equals(ExecuteAppletAction.NEVER));
+                }
+                return r;
             }
         }
 
         private static final class ShowPermanentA extends MyCommonSorter {
+
             @Override
             public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.ALWAYS));
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.ALWAYS));
+                }
+                return r;
+            }
+
+        }
+
+        private static final class ShowPermanentN extends MyCommonSorter {
+
+            @Override
+            public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.NEVER));
+                }
+                return r;
             }
         }
 
-        private static final class ShowPermanentN  extends MyCommonSorter {
+        private static final class ShowTemporarilyDecisions extends MyCommonSorter {
 
             @Override
             public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.NEVER));
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.YES) || o.equals(ExecuteAppletAction.NO));
+                }
+                return r;
             }
         }
 
-        private static final class ShowTemporarilyDecisions  extends MyCommonSorter {
+        private static final class ShowHasChosenYes extends MyCommonSorter {
 
             @Override
             public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.YES) || o.equals(ExecuteAppletAction.NO));
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.YES));
+                }
+                return r;
             }
+
         }
 
-        private static final class ShowHasChosenYes  extends MyCommonSorter {
+        private static final class ShowHasChosenNo extends MyCommonSorter {
 
             @Override
             public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.YES));
+                boolean r = false;
+                for (int i = 0; i < AppletSecurityActions.REMEBER_COLUMNS_COUNT; i++) {
+                    ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), i);
+                    r = r || (o.equals(ExecuteAppletAction.NO));
+                }
+                return r;
             }
-           
-            
-        }
 
-        private static final class ShowHasChosenNo  extends MyCommonSorter {
-
-            @Override
-            public boolean include(Entry<? extends UnsignedAppletActionTableModel, ? extends Integer> entry) {
-                ExecuteAppletAction o = (ExecuteAppletAction) entry.getModel().getValueAt(entry.getIdentifier(), 0);
-                return (o.equals(ExecuteAppletAction.NO));
-            }
-            
         }
         public static final ShowAll showAll = new ShowAll();
         public static final ShowPermanents showPermanents = new ShowPermanents();
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/resources/Messages.properties
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Tue Apr 22 15:34:41 2014 +0200
@@ -293,15 +293,14 @@
 SRememberCodebase=For site <u>{0}</u>
 SUnsignedSummary=An unsigned Java application wants to run
 SUnsignedDetail=An unsigned application from the following location wants to run:<br/>  <u><a href="{0}" >{0}</a></u><br/>The page which made the request was:<br/>  <u><a href="{1}" >{1}</a></u><br/><br/><b>It is recommended you only run applications from sites you trust.</b> 
-SUnsignedAllowedBefore=<font color="green">You have accepted this applet previously.</font>
-SUnsignedRejectedBefore=<font color="red">You have rejected this applet previously.</font>
+SUnsignedAllowedBefore=<font color="green">You have accepted this applet previously - ({0}).</font>
+SUnsignedRejectedBefore=<font color="red">You have rejected this applet previously - ({0}).</font>
 SUnsignedQuestion=Allow the applet to run?
 SPartiallySignedSummary=Only parts of this application code are signed.
 SPartiallySignedDetail=This application contains both signed and unsigned code. While signed code is safe if you trust the provider, unsigned code may imply code outside of the trusted provider's control.
 SPartiallySignedQuestion=Do you wish to proceed and run this application anyway?
 SAuthenticationPrompt=The {0} server at {1} is requesting authentication. It says "{2}"
 SJNLPFileIsNotSigned=This application contains a digital signature in which the launching JNLP file is not signed.
-SAppletTitle=Applet title: {0}
 STrustedOnlyAttributeFailure=This application specifies Trusted-only as True in its Manifest. {0} and requests permission level: {1}. This is not allowed.
 STOAsignedMsgFully = The applet is fully signed
 STOAsignedMsgAndSandbox = The applet is fully signed and sandboxed
@@ -820,7 +819,8 @@
 APPEXTSECunsignedAppletActionNo=This applet was visited and denied
 APPEXTSECunsetAppletActionNo=This applet have not yet asked for this action
 APPEXTSECControlPanelExtendedAppletSecurityTitle=Extended applet security
-APPEXTSECguiTableModelTableColumnAction=Action
+APPEXTSECguiTableModelTableColumnActionUA=Unsigned applet Action
+APPEXTSECguiTableModelTableColumnActionMatchALACA=Library Action
 APPEXTSECguiTableModelTableColumnDateOfAction=Date of action
 APPEXTSECguiTableModelTableColumnDocumentBase=Document-base
 APPEXTSECguiTableModelTableColumnCodeBase=Code-base
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/resources/Messages_cs.properties
--- a/netx/net/sourceforge/jnlp/resources/Messages_cs.properties	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages_cs.properties	Tue Apr 22 15:34:41 2014 +0200
@@ -297,7 +297,6 @@
 SPartiallySignedQuestion=Chcete p\u0159esto pokra\u010dovat a spustit aplikaci?
 SAuthenticationPrompt=Server {0} na adrese {1} vy\u017eaduje ov\u011b\u0159en\u00ed. Zpr\u00e1va: \u201e{2}\u201c
 SJNLPFileIsNotSigned=Tato aplikace obsahuje digit\u00e1ln\u00ed podpis, v r\u00e1mci kter\u00e9ho v\u0161ak nen\u00ed podeps\u00e1n spou\u0161t\u011bn\u00fd soubor JNLP.
-SAppletTitle=N\u00e1zev apletu: {0}
 STrustedOnlyAttributeFailure=Element \u201etrusted-only\u201c v manifestu aplikace m\u00e1 hodnotu true. {0} a po\u017eaduje n\u00e1sleduj\u00edc\u00ed \u00farove\u0148 opr\u00e1vn\u011bn\u00ed: {1}. To nen\u00ed dovoleno.
 STOAsignedMsgFully= Aplet je kompletn\u011b podeps\u00e1n.
 STOAsignedMsgAndSandbox= Aplet je kompletn\u011b podeps\u00e1n a b\u011b\u017e\u00ed v izolovan\u00e9m prostoru (sandbox).
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Tue Apr 22 15:34:41 2014 +0200
@@ -31,7 +31,9 @@
 import java.security.KeyStore;
 import java.security.Policy;
 import java.security.Security;
+import java.text.DateFormat;
 import java.text.MessageFormat;
+import java.util.Date;
 import java.util.List;
 import java.util.ResourceBundle;
 
@@ -638,6 +640,10 @@
                 return "Missing resource: " + key;
         }
     }
+    
+    public static String getLocalisedTimeStamp(Date timestamp) {
+        return DateFormat.getInstance().format(timestamp);
+    };
 
     /**
      * Returns the localized resource string using the specified arguments.
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
--- a/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java	Tue Apr 22 15:34:41 2014 +0200
@@ -325,7 +325,7 @@
                 }
             }
         }
-        boolean a = SecurityDialogs.showMatchingALACAttributePanel(file.getTitle(), documentBase, usedUrls);
+        boolean a = SecurityDialogs.showMatchingALACAttributePanel(file, documentBase, usedUrls);
         if (!a) {
             throw new LaunchException("The application uses non-codebase resources, which do match its Application-Library-Allowable-Codebase Attribute, but was blocked from running by the user.");
         } else {
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/SecurityDialog.java
--- a/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Tue Apr 22 15:34:41 2014 +0200
@@ -55,7 +55,7 @@
 import net.sourceforge.jnlp.security.dialogs.AppletWarningPane;
 import net.sourceforge.jnlp.security.dialogs.CertWarningPane;
 import net.sourceforge.jnlp.security.dialogs.CertsInfoPane;
-import net.sourceforge.jnlp.security.dialogs.MatchingALACAttributePanel;
+import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.MatchingALACAttributePanel;
 import net.sourceforge.jnlp.security.dialogs.MissingALACAttributePanel;
 import net.sourceforge.jnlp.security.dialogs.MissingPermissionsAttributePanel;
 import net.sourceforge.jnlp.security.dialogs.MoreInfoPane;
@@ -63,6 +63,7 @@
 import net.sourceforge.jnlp.security.dialogs.SecurityDialogPanel;
 import net.sourceforge.jnlp.security.dialogs.SingleCertInfoPane;
 import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningDialog;
+import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel;
 import net.sourceforge.jnlp.util.ImageResources;
 import net.sourceforge.jnlp.util.ScreenFinder;
 import net.sourceforge.jnlp.util.logging.OutputController;
@@ -325,7 +326,7 @@
         else if (dialogType == DialogType.MISSING_ALACA)
             panel = new MissingALACAttributePanel(this, (String) extras[0], (String) extras[1], (String) extras[2]);
         else if (dialogType == DialogType.MATCHING_ALACA)
-            panel = new MatchingALACAttributePanel(this, (String) extras[0], (String) extras[1], (String) extras[2]);
+            panel = AppTrustWarningDialog.matchingAlaca(this, (JNLPFile) extras[0], (String) extras[1], (String) extras[2]);
 
         add(panel, BorderLayout.CENTER);
     }
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/SecurityDialogs.java
--- a/netx/net/sourceforge/jnlp/security/SecurityDialogs.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialogs.java	Tue Apr 22 15:34:41 2014 +0200
@@ -54,9 +54,13 @@
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
+import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
+import static net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation.getStoredAction;
 import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel.AppSigningWarningAction;
 import net.sourceforge.jnlp.util.UrlUtils;
+import net.sourceforge.jnlp.util.logging.OutputController;
 
 /**
  * <p>
@@ -167,6 +171,7 @@
      * Shows a warning dialog for when a plugin applet is unsigned.
      * This is used with 'high-security' setting.
      *
+     * @param file
      * @return true if permission was granted by the user, false otherwise.
      */
     public static AppSigningWarningAction showUnsignedWarningDialog(JNLPFile file) {
@@ -192,6 +197,7 @@
      * @param accessType the type of warning dialog to show
      * @param file the JNLPFile associated with this warning
      * @param certVerifier the JarCertVerifier used to verify this application
+     * @param securityDelegate
      *
      * @return RUN if the user accepted the certificate, SANDBOX if the user
      * wants the applet to run with only sandbox permissions, or CANCEL if the
@@ -219,6 +225,9 @@
     /**
      * Shows a warning dialog for when an applet or application is partially signed.
      *
+     * @param file
+     * @param certVerifier
+     * @param securityDelegate
      * @return true if permission was granted by the user, false otherwise.
      */
     public static AppSigningWarningAction showPartiallySignedWarningDialog(JNLPFile file, CertVerifier certVerifier,
@@ -281,18 +290,40 @@
         return getIntegerResponseAsBoolean(selectedValue);
     } 
      
-     public static boolean showMatchingALACAttributePanel(String title, URL codeBase, Set<URL> remoteUrls) {
+     public static boolean showMatchingALACAttributePanel(JNLPFile file, URL codeBase, Set<URL> remoteUrls) {
+         
+        ExecuteAppletAction storedAction = getStoredAction(file, AppletSecurityActions.MATCHING_ALACA_ACTION);
+        OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Stored action for matching alaca at " + file.getCodeBase() +" was " + storedAction);
+        
+        if (storedAction != null){
+            if (storedAction == ExecuteAppletAction.ALWAYS){
+                return true;
+            }
+            if (storedAction == ExecuteAppletAction.NEVER){
+                return false;
+            }
+        }
+        
 
         if (!shouldPromptUser()) {
             return false;
         }
 
-        SecurityDialogMessage message = new SecurityDialogMessage();
-        message.dialogType = DialogType.MATCHING_ALACA;
-        message.extras = new Object[]{title, codeBase.toString(), UrlUtils.setOfUrlsToHtmlList(remoteUrls)};
-        Object selectedValue = getUserResponse(message);
-        return getIntegerResponseAsBoolean(selectedValue);
-    } 
+         SecurityDialogMessage message = new SecurityDialogMessage();
+         message.dialogType = DialogType.MATCHING_ALACA;
+         message.extras = new Object[]{file, codeBase.toString(), UrlUtils.setOfUrlsToHtmlList(remoteUrls)};
+         AppSigningWarningAction selectedValue = (AppSigningWarningAction) getUserResponse(message);
+
+         if (selectedValue != null) {
+             OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Decided action for matching alaca at " + file.getCodeBase() + " was " + selectedValue.getAction());
+             UnsignedAppletTrustConfirmation.updateAppletAction(file, selectedValue.getAction(), selectedValue.rememberForCodeBase(), AppletSecurityActions.MATCHING_ALACA_ACTION);
+             return selectedValue.getAction() == ExecuteAppletAction.ALWAYS || selectedValue.getAction() == ExecuteAppletAction.YES;
+         }
+
+         OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Decided action for matching alaca at " + file.getCodeBase() + " was " + null);
+         return false;
+
+    }
      
     /**
      * FIXME This is unused. Remove it?
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/AppletSecurityActions.java	Tue Apr 22 15:34:41 2014 +0200
@@ -40,19 +40,30 @@
 
 public class AppletSecurityActions {
     private final List<ExecuteAppletAction> actions = new ArrayList<>();
+    public static final int UNSIGNED_APPLET_ACTION = 0;
+    public static final int MATCHING_ALACA_ACTION = 1;
+    public static final int REMEBER_COLUMNS_COUNT = 2;
 
     
+    public static AppletSecurityActions createDefault() {
+        AppletSecurityActions asas = new AppletSecurityActions();
+        asas.setUnsignedAppletAction(ExecuteAppletAction.UNSET);
+        asas.setMatchingAlacaAction(ExecuteAppletAction.UNSET);
+        return asas;
+    }
     /*
-     * backward compatibility method for base, UnsignedAppletTrustConfirmation usage
-     * FIXME - remove
+     * quick setup method when new item , with one action, is added
      */
-    public static AppletSecurityActions fromAction(ExecuteAppletAction s) {
+    public static AppletSecurityActions fromAction(int id, ExecuteAppletAction s) {
         if (s == null){
             s = ExecuteAppletAction.UNSET;
         }
-        return fromString(s.toChar());
+        AppletSecurityActions asas = new AppletSecurityActions();
+        asas.setAction(id, s);
+        return asas;
     }
     
+    
     static AppletSecurityActions fromString(String s) {
         if (s == null) {
             s = "";
@@ -67,14 +78,14 @@
         return asas;
     }
 
-    ExecuteAppletAction getAction(int i) {
+    public ExecuteAppletAction getAction(int i) {
         if (i>= actions.size()){
             return ExecuteAppletAction.UNSET;
         }
         return actions.get(i);
     }
     
-    void setAction(int i, ExecuteAppletAction a) {
+    public void setAction(int i, ExecuteAppletAction a) {
         while (actions.size() <= i){
             actions.add(ExecuteAppletAction.UNSET);
         }
@@ -83,21 +94,47 @@
     
     
     public ExecuteAppletAction getUnsignedAppletAction() {
-        return getAction(0);
+        return getAction(UNSIGNED_APPLET_ACTION);
     }
     
     public void setUnsignedAppletAction(ExecuteAppletAction a) {
-        actions.set(0,a);
+       setAction(UNSIGNED_APPLET_ACTION,a);
+    }
+    
+    
+    public ExecuteAppletAction getMatchingAlacaAction() {
+        return getAction(MATCHING_ALACA_ACTION);
+    }
+    
+    public void setMatchingAlacaAction(ExecuteAppletAction a) {
+        setAction(MATCHING_ALACA_ACTION, a);
     }
 
     @Override
     public String toString() {
+        return toShortString();
+    }
+
+    public String toLongString() {
+        StringBuilder sb = new StringBuilder();
+        for (ExecuteAppletAction executeAppletAction : actions) {
+            sb.append(executeAppletAction.toString()).append("; ");
+        }
+        return sb.toString();
+    }
+    
+    
+    public String toShortString() {
         StringBuilder sb = new StringBuilder();
         for (ExecuteAppletAction executeAppletAction : actions) {
             sb.append(executeAppletAction.toChar());
         }
         return sb.toString();
     }
+    
+    public int getRealCount() {
+        return actions.size();
+    }
 
     
     /**
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionEntry.java	Tue Apr 22 15:34:41 2014 +0200
@@ -37,13 +37,23 @@
 
 import java.io.IOException;
 import java.io.Writer;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Locale;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.Translator;
 
+/**
+ * 
+ * The name of this class is legacy.
+ * Now it is used to keep state of all remembered security decisions
+ * 
+ */
 public class UnsignedAppletActionEntry {
 
-    private AppletSecurityActions unsignedAppletAction;
+    private AppletSecurityActions appletSecurityActions;
     private Date timeStamp;
     private UrlRegEx documentBase;
     private UrlRegEx codeBase;
@@ -67,7 +77,7 @@
     }
 
     public UnsignedAppletActionEntry(AppletSecurityActions unsignedAppletAction, Date timeStamp, UrlRegEx documentBase, UrlRegEx codeBase, List<String> archives) {
-        this.unsignedAppletAction = unsignedAppletAction;
+        this.appletSecurityActions = unsignedAppletAction;
         this.timeStamp = timeStamp;
         this.documentBase = documentBase;
         this.codeBase = codeBase;
@@ -86,7 +96,7 @@
     }
 
     private String serializeToReadableAndParseableString() {
-        return unsignedAppletAction.toString()
+        return appletSecurityActions.toString()
                 + " " + ((timeStamp == null) ? "1" : timeStamp.getTime())
                 + " " + ((documentBase == null) ? "" : documentBase.getRegEx())
                 + " " + ((codeBase == null) ? "" : codeBase.getRegEx())
@@ -96,6 +106,10 @@
     public Date getTimeStamp() {
         return timeStamp;
     }
+    
+    public String getLocalisedTimeStamp() {
+        return JNLPRuntime.getLocalisedTimeStamp(timeStamp);
+    }
 
     public UrlRegEx getDocumentBase() {
         return documentBase;
@@ -109,12 +123,12 @@
         this.documentBase = documentBase;
     }
 
-    public ExecuteAppletAction getUnsignedAppletAction() {
-        return unsignedAppletAction.getUnsignedAppletAction();
+    public AppletSecurityActions getAppletSecurityActions() {
+        return appletSecurityActions;
     }
 
-    public void setUnsignedAppletAction(ExecuteAppletAction unsignedAppletAction) {
-        this.unsignedAppletAction.setUnsignedAppletAction(unsignedAppletAction);
+    public void setAppletSecurityActions(AppletSecurityActions actions) {
+        this.appletSecurityActions = actions;
     }
 
     public UrlRegEx getCodeBase() {
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletActionStorage.java	Tue Apr 22 15:34:41 2014 +0200
@@ -66,34 +66,38 @@
      * @param documentBase
      * @param codeBase
      * @param archives
+     * @param id of AppletSecurityAction's ExecuteAppletAction to be used for "strong" search
      * @return a matching unsigned applet action entry
      */
-    public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives);
+    public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives, Integer id);
 
     /**
      * Shortcut {@code getMatchingItem(documentBase, null, null, null)}
      *
      * @param documentBase
+     * @param id of AppletSecurityAction's ExecuteAppletAction to be used for "strong" search
      * @return a matching unsigned applet action entry
      */
-    public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase);
+    public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase, Integer id);
 
     /**
      * Shortcut {@code getMatchingItem(null, codeBase, null, null)}
      *
      * @param codeBase
+     * @param id of AppletSecurityAction's ExecuteAppletAction to be used for "strong" search
      * @return a matching unsigned applet action entry
      */
-    public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase);
+    public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase, Integer id);
 
     /**
      * Shortcut {@code getMatchingItem(documentBase, codeBase, null, null)}
      *
      * @param documentBase
      * @param codeBase
+     * @param id of AppletSecurityAction's ExecuteAppletAction to be used for "strong" search
      * @return a matching unsigned applet action entry
      */
-    public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase);
+    public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase, Integer id);
 
     /**
      * Will add new record. Note that regexes are stored for bases matching.
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Tue Apr 22 15:34:41 2014 +0200
@@ -78,37 +78,45 @@
      * and then the global policy.
      * 
      * @param file the plugin file
+     * @param id of wonted  action
      * @return the remembered decision
      */
-    public static ExecuteAppletAction getStoredAction(JNLPFile file) {
+    public static UnsignedAppletActionEntry getStoredEntry(JNLPFile file, int id) {
         UnsignedAppletActionStorage userActionStorage = securitySettings.getUnsignedAppletActionCustomStorage();
         UnsignedAppletActionStorage globalActionStorage = securitySettings.getUnsignedAppletActionGlobalStorage();
 
-        UnsignedAppletActionEntry globalEntry = getMatchingItem(globalActionStorage, file);
-        UnsignedAppletActionEntry userEntry = getMatchingItem(userActionStorage, file);
+        UnsignedAppletActionEntry globalEntry = getMatchingItem(globalActionStorage, file, id);
+        UnsignedAppletActionEntry userEntry = getMatchingItem(userActionStorage, file, id);
 
-        ExecuteAppletAction globalAction = globalEntry == null ? null : globalEntry.getUnsignedAppletAction();
-        ExecuteAppletAction userAction = userEntry == null ? null : userEntry.getUnsignedAppletAction();
+        ExecuteAppletAction globalAction = globalEntry == null ? null : globalEntry.getAppletSecurityActions().getAction(id);
+        ExecuteAppletAction userAction = userEntry == null ? null : userEntry.getAppletSecurityActions().getAction(id);
 
         if (userAction == ExecuteAppletAction.ALWAYS || userAction == ExecuteAppletAction.NEVER) {
-            return userAction;
+            return userEntry;
         } else if (globalAction == ExecuteAppletAction.ALWAYS || globalAction == ExecuteAppletAction.NEVER) {
-            return globalAction;
+            return globalEntry;
         } else {
-            return userAction;
+            return userEntry;
         }
     }
+    public static ExecuteAppletAction getStoredAction(JNLPFile file, int id) {
+        UnsignedAppletActionEntry x = getStoredEntry(file, id);
+        if (x != null) {
+            return x.getAppletSecurityActions().getAction(id);
+        }
+        return null;
+    }
 
-    private static UnsignedAppletActionEntry getMatchingItem(UnsignedAppletActionStorage actionStorage, JNLPFile file) {
+    private static UnsignedAppletActionEntry getMatchingItem(UnsignedAppletActionStorage actionStorage, JNLPFile file, int id) {
         return actionStorage.getMatchingItem(
                 UrlUtils.normalizeUrlAndStripParams(file.getSourceLocation(), true /* encode local files */).toString(), 
                 UrlUtils.normalizeUrlAndStripParams(file.getCodeBase(), true /* encode local files */).toString(), 
-                toRelativePaths(getJars(file), file.getCodeBase().toString()));
+                toRelativePaths(getJars(file), file.getCodeBase().toString()), id);
     }
 
     /* Extract the archives as relative paths */
     static List<String> toRelativePaths(List<String> paths, String rootPath) {
-        List<String> fileNames = new ArrayList<String>();
+        List<String> fileNames = new ArrayList<>();
         for (String path : paths) {
             if (path.startsWith(rootPath)) {
                 fileNames.add(path.substring(rootPath.length()));
@@ -119,20 +127,12 @@
         return fileNames;
     }
 
-    private static void updateAppletAction(JNLPFile file, ExecuteAppletAction behaviour, boolean rememberForCodeBase) {
+    public static void updateAppletAction(JNLPFile file, ExecuteAppletAction behaviour, boolean rememberForCodeBase, int id) {
         UnsignedAppletActionStorage userActionStorage = securitySettings.getUnsignedAppletActionCustomStorage();
 
         userActionStorage.lock(); // We should ensure this operation is atomic
         try {
-            UnsignedAppletActionEntry oldEntry = getMatchingItem(userActionStorage, file);
-
-            /* Update, if entry exists */
-            if (oldEntry != null) {
-                oldEntry.setUnsignedAppletAction(behaviour);
-                oldEntry.setTimeStamp(new Date());
-                userActionStorage.update(oldEntry);
-                return;
-            }
+            UnsignedAppletActionEntry oldEntry = getMatchingItem(userActionStorage, file, id);
 
             URL codebase = UrlUtils.normalizeUrlAndStripParams(file.getCodeBase(), true /* encode local files */);
             URL documentbase = UrlUtils.normalizeUrlAndStripParams(file.getSourceLocation(), true /* encode local files */);
@@ -146,9 +146,20 @@
                 documentbaseRegex = new UrlRegEx("\\Q" + documentbase + "\\E"); // Match only this applet
                 archiveMatches = toRelativePaths(getJars(file), file.getCodeBase().toString()); // Match only this applet
             }
+            
+            /* Update, if entry exists */
+            if (oldEntry != null) {
+                oldEntry.getAppletSecurityActions().setAction(id, behaviour);
+                oldEntry.setTimeStamp(new Date());
+                oldEntry.setDocumentBase(documentbaseRegex);
+                oldEntry.setCodeBase(codebaseRegex);
+                oldEntry.setArchives(archiveMatches);
+                userActionStorage.update(oldEntry);
+                return;
+            }
 
             UnsignedAppletActionEntry entry = new UnsignedAppletActionEntry(
-                    AppletSecurityActions.fromAction(behaviour), 
+                    AppletSecurityActions.fromAction(id, behaviour), 
                     new Date(),
                     documentbaseRegex, 
                     codebaseRegex,
@@ -185,7 +196,7 @@
             return;
         }
 
-        ExecuteAppletAction storedAction = getStoredAction(file);
+        ExecuteAppletAction storedAction = getStoredAction(file, AppletSecurityActions.UNSIGNED_APPLET_ACTION);
         OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Stored action for unsigned applet at " + file.getCodeBase() +" was " + storedAction);
 
         boolean appletOK;
@@ -202,7 +213,7 @@
             appletOK = (executeAction == ExecuteAppletAction.YES || executeAction == ExecuteAppletAction.ALWAYS);
 
             if (executeAction != null) {
-                updateAppletAction(file, executeAction, warningResponse.rememberForCodeBase());
+                updateAppletAction(file, executeAction, warningResponse.rememberForCodeBase(), AppletSecurityActions.UNSIGNED_APPLET_ACTION);
             }
 
             OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Decided action for unsigned applet at " + file.getCodeBase() +" was " + executeAction);
@@ -228,7 +239,7 @@
             return;
         }
 
-        ExecuteAppletAction storedAction = getStoredAction(file);
+        ExecuteAppletAction storedAction = getStoredAction(file, AppletSecurityActions.UNSIGNED_APPLET_ACTION);
         OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Stored action for partially signed applet at " + file.getCodeBase() + " was " + storedAction);
 
         boolean appletOK;
@@ -250,7 +261,7 @@
                     || executeAction == ExecuteAppletAction.SANDBOX);
 
             if (executeAction != null) {
-                updateAppletAction(file, executeAction, warningResponse.rememberForCodeBase());
+                updateAppletAction(file, executeAction, warningResponse.rememberForCodeBase(),AppletSecurityActions.UNSIGNED_APPLET_ACTION);
             }
 
             OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Decided action for unsigned applet at " + file.getCodeBase() + " was " + executeAction);
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageExtendedImpl.java	Tue Apr 22 15:34:41 2014 +0200
@@ -38,6 +38,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Date;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UrlRegEx;
@@ -85,11 +86,15 @@
                     readContents();
                     for (int i = 0; i < items.size(); i++) {
                         UnsignedAppletActionEntry unsignedAppletActionEntry = items.get(i);
-                        if (unsignedAppletActionEntry.getUnsignedAppletAction() == unsignedAppletAction) {
-                            items.remove(i);
-                            i--;
+                        AppletSecurityActions actions = unsignedAppletActionEntry.getAppletSecurityActions();
+                        for (int j = 0; j < actions.getRealCount(); j++) {
+                            ExecuteAppletAction action = actions.getAction(j);
+                            if (action == unsignedAppletAction) {
+                                items.remove(i);
+                                i--;
+                                break; //actions loop
+                            }
                         }
-
                     }
                     writeContents();
                 } catch (IOException e) {
@@ -156,18 +161,21 @@
                     }
 
                     if (columnIndex == 0) {
-                        source.setUnsignedAppletAction((ExecuteAppletAction) aValue);
+                        source.getAppletSecurityActions().setUnsignedAppletAction((ExecuteAppletAction) aValue);
                     }
                     if (columnIndex == 1) {
+                        source.getAppletSecurityActions().setMatchingAlacaAction((ExecuteAppletAction) aValue);
+                    }
+                    if (columnIndex == 2) {
                         source.setTimeStamp((Date) aValue);
                     }
-                    if (columnIndex == 2) {
+                    if (columnIndex == 3) {
                         source.setDocumentBase(new UrlRegEx((String) aValue));
                     }
-                    if (columnIndex == 3) {
+                    if (columnIndex == 4) {
                         source.setCodeBase(new UrlRegEx((String) aValue));
                     }
-                    if (columnIndex == 4) {
+                    if (columnIndex == 5) {
                         source.setArchives(UnsignedAppletActionEntry.createArchivesList((String) aValue));
                     }
 
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImpl.java	Tue Apr 22 15:34:41 2014 +0200
@@ -131,17 +131,21 @@
     }
 
     @Override
-    public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives) {
+    public UnsignedAppletActionEntry getMatchingItem(String documentBase, String codeBase, List<String> archives, Integer id) {
         List<UnsignedAppletActionEntry> results = getMatchingItems(documentBase, codeBase, archives);
         if (results == null || results.isEmpty()) {
             return null;
         }
+        //no comaprsion id provided
+        if (id  == null){
+            return results.get(0);    
+        }
         // Chose the first result, unless we find a 'stronger' result
         // Actions such as 'always accept' or 'always reject' are 'stronger' than
         // the hints 'was accepted' or 'was rejected'.
         for (UnsignedAppletActionEntry candidate : results) {
-                if (candidate.getUnsignedAppletAction() == ExecuteAppletAction.ALWAYS
-                    || candidate.getUnsignedAppletAction() == ExecuteAppletAction.NEVER) {
+                if (candidate.getAppletSecurityActions().getAction(id) == ExecuteAppletAction.ALWAYS
+                    || candidate.getAppletSecurityActions().getAction(id) == ExecuteAppletAction.NEVER) {
                     //return first found strong
                     return  candidate;
                 }
@@ -228,17 +232,17 @@
     }
 
     @Override
-    public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase) {
-        return getMatchingItem(documentBase, null, null);
+    public UnsignedAppletActionEntry getMatchingItemByDocumentBase(String documentBase, Integer id) {
+        return getMatchingItem(documentBase, null, null, id);
     }
 
     @Override
-    public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase) {
-        return getMatchingItem(null, codeBase, null);
+    public UnsignedAppletActionEntry getMatchingItemByCodeBase(String codeBase, Integer id) {
+        return getMatchingItem(null, codeBase, null, id);
     }
 
     @Override
-    public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase) {
-        return getMatchingItem(documentBase, codeBase, null);
+    public UnsignedAppletActionEntry getMatchingItemByBases(String documentBase, String codeBase, Integer id) {
+        return getMatchingItem(documentBase, codeBase, null, id);
     }
 }
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/MatchingALACAttributePanel.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/MatchingALACAttributePanel.java	Thu Apr 17 14:53:10 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/* 
- Copyright (C) 2008 Red Hat, Inc.
-
- This file is part of IcedTea.
-
- IcedTea is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published by
- the Free Software Foundation, version 2.
-
- IcedTea is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with IcedTea; see the file COPYING.  If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
-
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library.  Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
-
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module.  An independent module is a module which is not derived from
- or based on this library.  If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so.  If you do not wish to do so, delete this
- exception statement from your version.
- */
-package net.sourceforge.jnlp.security.dialogs;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Desktop;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.Image;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.Set;
-import javax.imageio.ImageIO;
-
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JEditorPane;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-import net.sourceforge.jnlp.runtime.Translator;
-import net.sourceforge.jnlp.security.SecurityDialog;
-import net.sourceforge.jnlp.util.UrlUtils;
-import net.sourceforge.jnlp.util.logging.OutputController;
-
-/**
- * http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/manifest.html#app_library
- */
-public class MatchingALACAttributePanel extends SecurityDialogPanel {
-
-    public MatchingALACAttributePanel(SecurityDialog x, String title, String codebase, String remoteUrls) {
-        super(x);
-        try {
-            addComponents(title, codebase, remoteUrls);
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-        if (x != null) {
-            x.setMinimumSize(new Dimension(600, 400));
-        }
-    }
-
-    protected final void addComponents(String title, String codebase, String remoteUrls) throws IOException {
-
-        URL imgUrl = this.getClass().getResource("/net/sourceforge/jnlp/resources/question.png");
-        ImageIcon icon;
-        Image img = ImageIO.read(imgUrl);
-        icon = new ImageIcon(img);
-        String topLabelText = Translator.R("ALACAMatchingMainTitle", title, codebase, remoteUrls);
-        String bottomLabelText = Translator.R("ALACAMatchingInfo");
-
-        JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.CENTER);
-        topLabel.setFont(new Font(topLabel.getFont().toString(),
-                Font.BOLD, 12));
-        JPanel topPanel = new JPanel(new BorderLayout());
-        topPanel.setBackground(Color.WHITE);
-        topPanel.add(topLabel, BorderLayout.CENTER);
-        topPanel.setPreferredSize(new Dimension(400, 80));
-        topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
-        JEditorPane bottomLabel = new JEditorPane("text/html", htmlWrap(bottomLabelText));
-        bottomLabel.setEditable(false);
-        bottomLabel.addHyperlinkListener(new HyperlinkListener() {
-            @Override
-            public void hyperlinkUpdate(HyperlinkEvent e) {
-                try {
-                    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
-                        Desktop.getDesktop().browse(e.getURL().toURI());
-                    }
-                } catch (IOException ex) {
-                    OutputController.getLogger().log(ex);
-                } catch (URISyntaxException ex) {
-                    OutputController.getLogger().log(ex);
-                }
-            }
-        });
-        JPanel infoPanel = new JPanel(new BorderLayout());
-        infoPanel.add(bottomLabel, BorderLayout.CENTER);
-        infoPanel.setPreferredSize(new Dimension(400, 80));
-        infoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-        bottomLabel.setBackground(infoPanel.getBackground());
-
-        //run and cancel buttons
-        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-
-        JButton yes = new JButton(Translator.R("ButYes"));
-        JButton no = new JButton(Translator.R("ButNo"));
-        JCheckBox remeber = new JCheckBox(htmlWrap(Translator.R("SRememberOption")));
-        int buttonWidth = yes.getMinimumSize().width;
-        int buttonHeight = yes.getMinimumSize().height;
-        Dimension d = new Dimension(buttonWidth, buttonHeight);
-        yes.setPreferredSize(d);
-        no.setPreferredSize(d);
-        yes.addActionListener(createSetValueListener(parent, 0));
-        no.addActionListener(createSetValueListener(parent, 1));
-        initialFocusComponent = no;
-        buttonPanel.add(remeber);
-        buttonPanel.add(yes);
-        buttonPanel.add(no);
-        buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-        //all of the above
-        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-        add(topPanel);
-        add(infoPanel);
-        add(buttonPanel);
-
-    }
-
-    public static void main(String[] args) throws MalformedURLException {
-        Set<URL> s = new HashSet<URL>();
-        s.add(new URL("http:/blah.com/blah"));
-        s.add(new URL("http:/blah.com/blah/blah"));
-        MatchingALACAttributePanel w = new MatchingALACAttributePanel(null, "HelloWorld", "http://nbblah.url", UrlUtils.setOfUrlsToHtmlList(s));
-        JFrame f = new JFrame();
-        f.setSize(600, 400);
-        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        f.add(w, BorderLayout.CENTER);
-        f.setVisible(true);
-    }
-}
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java	Tue Apr 22 15:34:41 2014 +0200
@@ -47,6 +47,7 @@
  * A panel that confirms that the user is OK with unsigned code running.
  */
 public class AppTrustWarningDialog extends SecurityDialogPanel {
+    private ActionChoiceListener listener;
 
     private AppTrustWarningDialog(final SecurityDialog dialog) {
         super(dialog);
@@ -63,8 +64,21 @@
         warningDialog.add(new PartiallySignedAppTrustWarningPanel(file, warningDialog.getActionChoiceListener(), dialog, securityDelegate));
         return warningDialog;
     }
+    
+    public static AppTrustWarningDialog matchingAlaca(SecurityDialog x, JNLPFile file, String codebase, String remoteUrls) {
+        final AppTrustWarningDialog warningDialog = new AppTrustWarningDialog(x);
+        warningDialog.add(new MatchingALACAttributePanel(x, file, codebase, remoteUrls, warningDialog.getActionChoiceListener()));
+        return warningDialog;
+    }
 
     private ActionChoiceListener getActionChoiceListener() {
+        if (listener == null) {
+            listener = createActionChoiceListener();
+        }
+        return listener;
+    }
+
+    private ActionChoiceListener createActionChoiceListener() {
         return new ActionChoiceListener() {
             @Override
             public void actionChosen(final AppSigningWarningAction action) {
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -68,6 +68,8 @@
 import javax.swing.event.HyperlinkListener;
 
 import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.PluginBridge;
+import static net.sourceforge.jnlp.runtime.Translator.R;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExtendedAppletSecurityHelp;
 import net.sourceforge.jnlp.util.ScreenFinder;
@@ -215,7 +217,17 @@
     }
 
     protected String getAppletTitle() {
-        return R("SAppletTitle", file.getTitle());
+        String title;
+        try {
+            if (file instanceof PluginBridge) {
+                title = file.getTitle();
+            } else {
+                title = file.getInformation().getTitle();
+            }
+        } catch (Exception e) {
+            title = "";
+        }
+        return title;
     }
 
     private void setupInfoPanel() {
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/MatchingALACAttributePanel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/MatchingALACAttributePanel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -0,0 +1,133 @@
+/* 
+ Copyright (C) 2008 Red Hat, Inc.
+
+ This file is part of IcedTea.
+
+ IcedTea is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, version 2.
+
+ IcedTea is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with IcedTea; see the file COPYING.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library.  Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module.  An independent module is a module which is not derived from
+ or based on this library.  If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so.  If you do not wish to do so, delete this
+ exception statement from your version.
+ */
+package net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.ParseException;
+import net.sourceforge.jnlp.runtime.Translator;
+import static net.sourceforge.jnlp.runtime.Translator.R;
+import net.sourceforge.jnlp.security.SecurityDialog;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
+import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
+import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
+import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
+import net.sourceforge.jnlp.util.UrlUtils;
+
+/**
+ * http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/manifest.html#app_library
+ */
+public class MatchingALACAttributePanel extends AppTrustWarningPanel {
+    private final String title;
+    private final String codebase;
+    private final String remoteUrls;
+
+    public MatchingALACAttributePanel(SecurityDialog x, JNLPFile file,  String codebase, String remoteUrls, ActionChoiceListener actionChoiceListener) {
+        super(file, actionChoiceListener);
+        this.title = super.getAppletTitle();
+        this.codebase = codebase;
+        this.remoteUrls = remoteUrls;
+        TOP_PANEL_HEIGHT = 250;
+        addComponents();
+        if (x != null) {
+            x.setMinimumSize(new Dimension(600, 400));
+        }
+    }
+    
+    @Override
+    protected ImageIcon getInfoImage() {
+        final String location = "net/sourceforge/jnlp/resources/question.png";
+        return new ImageIcon(ClassLoader.getSystemClassLoader().getResource(location));
+    }
+    
+     @Override
+    protected String getTopPanelText() {
+        return htmlWrap(Translator.R("ALACAMatchingMainTitle", title, codebase, remoteUrls));
+    }
+    
+    @Override
+    protected String getInfoPanelText() {
+        String r = Translator.R("ALACAMatchingInfo");
+        UnsignedAppletActionEntry rememberedEntry = UnsignedAppletTrustConfirmation.getStoredEntry(file, AppletSecurityActions.MATCHING_ALACA_ACTION);
+        if (rememberedEntry != null) {
+            ExecuteAppletAction rememberedAction = rememberedEntry.getAppletSecurityActions().getMatchingAlacaAction();
+            if (rememberedAction == ExecuteAppletAction.YES) {
+                r += "<br>" + R("SUnsignedAllowedBefore", rememberedEntry.getLocalisedTimeStamp());
+            } else if (rememberedAction == ExecuteAppletAction.NO) {
+                r += "<br>" + R("SUnsignedRejectedBefore", rememberedEntry.getLocalisedTimeStamp());
+            }
+        }
+        return r;
+    }
+    
+    @Override
+    protected String getQuestionPanelText() {
+        return "";//htmlWrap(Translator.R("SRememberOption"));
+    }
+
+    @Override
+    public String getAppletTitle(){
+        return "";
+    }
+    
+
+    public static void main(String[] args) throws MalformedURLException, IOException, ParseException {
+        Set<URL> s = new HashSet<URL>();
+        s.add(new URL("http:/blah.com/blah"));
+        s.add(new URL("http:/blah.com/blah/blah"));
+        MatchingALACAttributePanel w = new MatchingALACAttributePanel(null, new JNLPFile(new URL("http://www.geogebra.org/webstart/geogebra.jnlp")), "http://nbblah.url", UrlUtils.setOfUrlsToHtmlList(s), new ActionChoiceListener() {
+
+            @Override
+            public void actionChosen(AppSigningWarningAction action) {
+                
+            }
+        });
+        JFrame f = new JFrame();
+        f.setSize(600, 400);
+        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        f.add(w, BorderLayout.CENTER);
+        f.setVisible(true);
+    }
+}
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -49,7 +49,9 @@
 import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.SecurityUtil;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
+import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
 import net.sourceforge.jnlp.security.dialogs.TemporaryPermissionsButton;
 import net.sourceforge.jnlp.tools.CertInformation;
@@ -79,21 +81,6 @@
         addComponents();
     }
 
-    @Override
-    protected String getAppletTitle() {
-        String title;
-        try {
-            if (file instanceof PluginBridge) {
-                title = file.getTitle();
-            } else {
-                title = file.getInformation().getTitle();
-            }
-        } catch (Exception e) {
-            title = "";
-        }
-        return R("SAppletTitle", title);
-    }
-
     private String getAppletInfo() {
         Certificate c = jcv.getPublisher(null);
 
@@ -159,11 +146,14 @@
         String text = getAppletInfo();
         text += "<br><br>" + R(getInfoPanelTextKey(), file.getCodeBase(), file.getSourceLocation());
         text += "<br><br>" + getSigningInfo();
-        ExecuteAppletAction rememberedAction = UnsignedAppletTrustConfirmation.getStoredAction(file);
-        if (rememberedAction == ExecuteAppletAction.YES) {
-            text += "<br>" + R("SUnsignedAllowedBefore");
-        } else if (rememberedAction == ExecuteAppletAction.NO) {
-            text += "<br>" + R("SUnsignedRejectedBefore");
+        UnsignedAppletActionEntry rememberedEntry = UnsignedAppletTrustConfirmation.getStoredEntry(file, AppletSecurityActions.UNSIGNED_APPLET_ACTION);
+        if (rememberedEntry != null) {
+            ExecuteAppletAction rememberedAction = rememberedEntry.getAppletSecurityActions().getUnsignedAppletAction();
+            if (rememberedAction == ExecuteAppletAction.YES) {
+                text += "<br>" + R("SUnsignedAllowedBefore", rememberedEntry.getLocalisedTimeStamp());
+            } else if (rememberedAction == ExecuteAppletAction.NO) {
+                text += "<br>" + R("SUnsignedRejectedBefore", rememberedEntry.getLocalisedTimeStamp());
+            }
         }
         return htmlWrap(text);
     }
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningDialog.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningDialog.java	Thu Apr 17 14:53:10 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* Copyright (C) 2013 Red Hat, Inc.
-
-This file is part of IcedTea.
-
-IcedTea is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as published by
-the Free Software Foundation, version 2.
-
-IcedTea is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with IcedTea; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version.
- */
-
-package net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel;
-
-import net.sourceforge.jnlp.JNLPFile;
-import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel.ActionChoiceListener;
-import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel.AppSigningWarningAction;
-import net.sourceforge.jnlp.security.SecurityDialog;
-import net.sourceforge.jnlp.security.dialogs.SecurityDialogPanel;
-
-/**
- * A panel that confirms that the user is OK with unsigned code running.
- * 
- */
-public class UnsignedAppletTrustWarningDialog extends SecurityDialogPanel {
-
-    public UnsignedAppletTrustWarningDialog(SecurityDialog x, JNLPFile file) {
-        super(x);
-
-        add(new UnsignedAppletTrustWarningPanel(file,
-                new ActionChoiceListener() {
-                    @Override
-                    public void actionChosen(AppSigningWarningAction action) {
-                        parent.setValue(action);
-                        parent.dispose();
-                    }
-                })
-        );
-    }
-
-}
diff -r 951e9f8919fd netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningPanel.java
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningPanel.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/UnsignedAppletTrustWarningPanel.java	Tue Apr 22 15:34:41 2014 +0200
@@ -43,7 +43,9 @@
 import javax.swing.ImageIcon;
 import javax.swing.JFrame;
 import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
+import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletActionEntry;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
 
 
@@ -80,11 +82,14 @@
     @Override
     protected String getInfoPanelText() {
         String text = R(getInfoPanelTextKey(), file.getCodeBase(), file.getSourceLocation());
-        ExecuteAppletAction rememberedAction = UnsignedAppletTrustConfirmation.getStoredAction(file);
-        if (rememberedAction == ExecuteAppletAction.YES) {
-            text += "<br>" + R("SUnsignedAllowedBefore");
-        } else if (rememberedAction == ExecuteAppletAction.NO) {
-            text += "<br>" + R("SUnsignedRejectedBefore");
+        UnsignedAppletActionEntry rememberedEntry = UnsignedAppletTrustConfirmation.getStoredEntry(file, AppletSecurityActions.UNSIGNED_APPLET_ACTION);
+        if (rememberedEntry != null) {
+            ExecuteAppletAction rememberedAction = rememberedEntry.getAppletSecurityActions().getUnsignedAppletAction();
+            if (rememberedAction == ExecuteAppletAction.YES) {
+                text += "<br>" + R("SUnsignedAllowedBefore", rememberedEntry.getLocalisedTimeStamp());
+            } else if (rememberedAction == ExecuteAppletAction.NO) {
+                text += "<br>" + R("SUnsignedRejectedBefore", rememberedEntry.getLocalisedTimeStamp());
+            }
         }
         return htmlWrap(text);
     }
diff -r 951e9f8919fd tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java
--- a/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java	Thu Apr 17 14:53:10 2014 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/appletextendedsecurity/impl/UnsignedAppletActionStorageImplTest.java	Tue Apr 22 15:34:41 2014 +0200
@@ -41,6 +41,7 @@
 import java.io.IOException;
 import java.util.Arrays;
 import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityActions;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -52,6 +53,9 @@
     private static File f2;
     private static File f3;
     private static File f4;
+   
+    public static final int ZERO = AppletSecurityActions.UNSIGNED_APPLET_ACTION;
+    public static final int ONE = AppletSecurityActions.MATCHING_ALACA_ACTION;
 
     @BeforeClass
     public static void preapreTestFiles() throws IOException {
@@ -65,6 +69,9 @@
                 + "A 1 \\Qhttp://jmol.sourceforge.net/demo/atoms/\\E \\Qhttp://jmol.sourceforge.net/jmol/\\E JmolApplet0.jar\n"
                 + "A 1363278653454 \\Qhttp://www.walter-fendt.de/ph14e\\E.* \\Qhttp://www.walter-fendt.de\\E.*\n"
                 + "n 1363281783104 \\Qhttp://www.walter-fendt.de/ph14e/inclplane.htm\\E \\Qhttp://www.walter-fendt.de/ph14_jar/\\E Ph14English.jar,SchiefeEbene.jar"
+                + "yA 1 \\Qhttp://jmol.sourceforge.net/demo/atoms/\\E \\Qhttp://jmol.sourceforge.net/jmol/\\E JmolApplet0.jar\n"
+                + "Ay 1363278653454 \\Qhttp://www.walter-fendt.de/ph14e\\E.* \\Qhttp://www.walter-fendt.de\\E.*\n"
+                + "nn 1363281783104 \\Qhttp://www.walter-fendt.de/ph14e/inclplane.htm\\E \\Qhttp://www.walter-fendt.de/ph14_jar/\\E Ph14English.jar,SchiefeEbene.jar"
                 + "", f3);
     }
 
@@ -79,19 +86,19 @@
      @Test
     public void wildcards1() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f3);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("http://www.walter-fendt.de/ph14e/inclplane.htm", "http://www.walter-fendt.de/ph14_jar/", Arrays.asList(new String[]{"Ph14English.jar","SchiefeEbene.jar"}));
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("http://www.walter-fendt.de/ph14e/inclplane.htm", "http://www.walter-fendt.de/ph14_jar/", Arrays.asList(new String[]{"Ph14English.jar","SchiefeEbene.jar"}), ZERO);
         ServerAccess.logOutputReprint(r1.toString());
      }
      @Test
     public void allMatchingDocAndCode() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f1);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar1", "jar2"}));
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar1", "jar2"}), ZERO);
         Assert.assertNotNull("r1 should be found", r1);
-        UnsignedAppletActionEntry r3 = i1.getMatchingItem("blah", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r3 = i1.getMatchingItem("blah", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}), ZERO);
         Assert.assertNotNull("r3 should be found", r3);
-        UnsignedAppletActionEntry r4 = i1.getMatchingItem("blha", "blaBlam",  Arrays.asList(new String[]{"jar2", "wrong_jar"}));
+        UnsignedAppletActionEntry r4 = i1.getMatchingItem("blha", "blaBlam",  Arrays.asList(new String[]{"jar2", "wrong_jar"}), ZERO);
         Assert.assertNull("r4 should NOT be found", r4);
-        UnsignedAppletActionEntry r5 = i1.getMatchingItem("blaBla", "blaBlaBla",  Arrays.asList(new String[]{"jar2"}));
+        UnsignedAppletActionEntry r5 = i1.getMatchingItem("blaBla", "blaBlaBla",  Arrays.asList(new String[]{"jar2"}), ZERO);
         Assert.assertNull("r5 should NOT be found", r5);
 
     }
@@ -99,13 +106,13 @@
      @Test
     public void allMatchingDocAndStrictCode() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f2);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("whatever", "bla",  Arrays.asList(new String[]{"jar1", "jar2"}));
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("whatever", "bla",  Arrays.asList(new String[]{"jar1", "jar2"}), ZERO);
         Assert.assertNotNull("r1 should be found", r1);
-        UnsignedAppletActionEntry r3 = i1.getMatchingItem("whatever", null,  Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r3 = i1.getMatchingItem("whatever", null,  Arrays.asList(new String[]{"jar2", "jar1"}), ZERO);
         Assert.assertNotNull("r3 should be found", r3);
-        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBlam",  Arrays.asList(new String[]{"jar1", "jar2"}));
+        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBlam",  Arrays.asList(new String[]{"jar1", "jar2"}), ZERO);
         Assert.assertNull("r2 should NOT be found", r2);
-        UnsignedAppletActionEntry r4 = i1.getMatchingItem(null, "blaBlam", null);
+        UnsignedAppletActionEntry r4 = i1.getMatchingItem(null, "blaBlam", null, ZERO);
         Assert.assertNull("r4 should NOT be found", r4);
 
     }
@@ -113,19 +120,19 @@
      @Test
     public void allMatchingDocAndCodeWithNulls() {
         UnsignedAppletActionStorageImpl i1 = new UnsignedAppletActionStorageImpl(f1);
-        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla",  null);
+        UnsignedAppletActionEntry r1 = i1.getMatchingItem("bla", "blaBla",  null, ZERO);
         Assert.assertNotNull("r1 should be found", r1);
-        UnsignedAppletActionEntry r3 = i1.getMatchingItem("bla", "whatever", null);
+        UnsignedAppletActionEntry r3 = i1.getMatchingItem("bla", "whatever", null, ZERO);
         Assert.assertNotNull("r3 should be found", r3);
-        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r2 = i1.getMatchingItem("bla", "blaBla", Arrays.asList(new String[]{"jar2", "jar1"}), ZERO);
         Assert.assertNotNull("r2 should be found", r2);
-        UnsignedAppletActionEntry r4 = i1.getMatchingItem("bla", "blaBla",  null);
+        UnsignedAppletActionEntry r4 = i1.getMatchingItem("bla", "blaBla",  null, ZERO);
         Assert.assertNotNull("r4 should be found", r4);
-        UnsignedAppletActionEntry r5 = i1.getMatchingItem("", "blaBla",  Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r5 = i1.getMatchingItem("", "blaBla",  Arrays.asList(new String[]{"jar2", "jar1"}), ZERO);
         Assert.assertNotNull("r5 should be found", r5);
-        UnsignedAppletActionEntry r6 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar1"}));
+        UnsignedAppletActionEntry r6 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar1"}), ZERO);
         Assert.assertNotNull("r6 should be found", r6);
-        UnsignedAppletActionEntry r7 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar11"}));
+        UnsignedAppletActionEntry r7 = i1.getMatchingItem(null, null,  Arrays.asList(new String[]{"jar2", "jar11"}), ZERO);
         Assert.assertNull("r7 should NOT be found", r7);
 
 


More information about the distro-pkg-dev mailing list