From 97eb5a56ab9f27b7b222dcaadacdf355ffdccead Mon Sep 17 00:00:00 2001
From: zab2 <zab2@mail.i2p>
Date: Thu, 28 Mar 2019 02:04:21 +0000
Subject: [PATCH] add the UI bits of the access rules

---
 .../net/i2p/i2ptunnel/TunnelController.java   |  1 +
 .../net/i2p/i2ptunnel/ui/GeneralHelper.java   | 13 +++++++-
 .../net/i2p/i2ptunnel/ui/TunnelConfig.java    | 30 +++++++++++++++++--
 apps/i2ptunnel/jsp/editServer.jsi             |  4 ++-
 4 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java
index fe0cc9fe64..8a2bc87998 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java
@@ -934,6 +934,7 @@ public class TunnelController implements Logging {
     public String getDescription() { return _config.getProperty(PROP_DESCR); }
     public String getI2CPHost() { return _config.getProperty(PROP_I2CP_HOST); }
     public String getI2CPPort() { return _config.getProperty(PROP_I2CP_PORT); }
+    public String getFilter() { return _config.getProperty(PROP_FILTER); }
 
     /**
      *  Is it a client or server in the UI and I2P side?
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java
index 22a84977a1..0eeb289178 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java
@@ -48,6 +48,7 @@ public class GeneralHelper {
 
     protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
     protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
+    protected static final String PROP_FILTER_DEFINITION = "filterDefinition";
 
     private static final String OPT = TunnelController.PFX_OPTION;
 
@@ -615,11 +616,21 @@ public class GeneralHelper {
             return 1;
         if (getBooleanProperty(tunnel, PROP_ENABLE_BLACKLIST))
             return 2;
+        TunnelController tun = getController(tunnel);
+        if (tun.getFilter() != null)
+            return 3;
         return 0;
     }
     
     public String getAccessList(int tunnel) {
-        return getProperty(tunnel, "i2cp.accessList", "").replace(",", "\n");
+        switch(getAccessMode(tunnel)) {
+            case 0:
+            case 1:
+            case 2:
+                return getProperty(tunnel, "i2cp.accessList", "").replace(",", "\n");
+        }
+        TunnelController tun = getController(tunnel);
+        return FileUtil.readTextFile(tun.getFilter(), -1, true);
     }
     
     public String getJumpList(int tunnel) {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java
index f0a154e512..ee41235e2a 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java
@@ -9,6 +9,10 @@ import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
 import net.i2p.I2PAppContext;
 import net.i2p.client.I2PClient;
 import net.i2p.crypto.KeyGenerator;
@@ -75,6 +79,8 @@ public class TunnelConfig {
     private String _newProxyUser;
     private String _newProxyPW;
     private Destination _dest;
+    private boolean _filter;
+    private String _filterDefinition;
 
     public TunnelConfig() {
         _context = I2PAppContext.getGlobalContext();
@@ -304,6 +310,7 @@ public class TunnelConfig {
 
     protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
     protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
+    protected static final String PROP_FILTER = "filterDefinition";
 
     /**
      * Controls how other tunnels are checked for access.
@@ -323,6 +330,9 @@ public class TunnelConfig {
             _booleanOptions.remove(PROP_ENABLE_ACCESS_LIST);
             _booleanOptions.add(PROP_ENABLE_BLACKLIST);
             break;
+        case 3:
+            _filter = true;
+            break;
         default:
             _booleanOptions.remove(PROP_ENABLE_ACCESS_LIST);
             _booleanOptions.remove(PROP_ENABLE_BLACKLIST);
@@ -371,8 +381,9 @@ public class TunnelConfig {
     }
 
     public void setAccessList(String val) {
-        if (val != null)
-            _otherOptions.put("i2cp.accessList", val.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
+        if (val == null)
+            return;
+        _filterDefinition = val;
     }
 
     public void setJumpList(String val) {
@@ -617,6 +628,21 @@ public class TunnelConfig {
             _booleanOptions.add(TunnelController.PROP_LIMITS_SET);
             for (String p : _booleanServerOpts)
                 config.setProperty(OPT + p, Boolean.toString(_booleanOptions.contains(p)));
+            if (_filter) {
+                String dslFile = _context.getConfigDir() + File.separator + _name+".accessrules";
+                config.setProperty(TunnelController.PROP_FILTER, dslFile);
+                FileOutputStream fos = null;
+                try {
+                    fos = new FileOutputStream(dslFile);
+                    fos.write(_filterDefinition.getBytes());
+                } catch (IOException bad) {
+                    throw new RuntimeException("failed to save access rules", bad);
+                } finally {
+                    if (fos != null) try { fos.close(); } catch (IOException ignored) {}
+                }
+            } else {                
+               _otherOptions.put("i2cp.accessList", _filterDefinition.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
+            }
             for (String p : _otherServerOpts) {
                 if (_otherOptions.containsKey(p))
                     config.setProperty(OPT + p, _otherOptions.get(p));
diff --git a/apps/i2ptunnel/jsp/editServer.jsi b/apps/i2ptunnel/jsp/editServer.jsi
index 903db0b723..ee32bd5fff 100644
--- a/apps/i2ptunnel/jsp/editServer.jsi
+++ b/apps/i2ptunnel/jsp/editServer.jsi
@@ -533,12 +533,14 @@
                     <%=intl._t("Blacklist")%></label></span>
                 <span class="multiOption"><label title="<%=intl._t("Only allow listed clients to connect to this service")%>"><input value="1" type="radio" name="accessMode"<%=(editBean.getAccessMode(curTunnel).equals("1") ? " checked=\"checked\"" : "")%> class="tickbox" />
                     <%=intl._t("Whitelist")%></label></span>
+                <span class="multiOption"><label title="<%=intl._t("Advanced access list configuration")%>"><input value="3" type="radio" name="accessMode"<%=(editBean.getAccessMode(curTunnel).equals("3") ? " checked=\"checked\"" : "")%> class="tickbox" />
+                    <%=intl._t("Advanced")%></label></span>
             </td>
         </tr>
 
         <tr>
             <td colspan="2">
-                <b><%=intl._t("Access List")%></b> (<%=intl._t("Specify clients, 1 per line")%>)
+                <b><%=intl._t("Access List Description")%></b> (<%=intl._t("Specify clients, 1 per line or describe access list")%>)
             </td>
         </tr>
 
-- 
GitLab