diff --git a/MikroTikAPI/src/com/eightOceans/mikroTik/MtSentence.java b/MikroTikAPI/src/com/eightOceans/mikroTik/MtSentence.java index 83a6afa..0e374fd 100644 --- a/MikroTikAPI/src/com/eightOceans/mikroTik/MtSentence.java +++ b/MikroTikAPI/src/com/eightOceans/mikroTik/MtSentence.java @@ -26,7 +26,7 @@ public class MtSentence { break; } else if (w.contains("!trap")) { s.isTrap = true; - break; + //break; } else if (w.contains("!re")) { } else if (w.startsWith("=")) { @@ -42,7 +42,7 @@ public class MtSentence { } - if ((!s.isDone) && (!s.isTrap)) { + if ((!s.isDone) /*&& (!s.isTrap)*/) { s.words = newWords; } return s; @@ -63,6 +63,12 @@ public class MtSentence { return isTrap; } + public String getTrapMsg() { + if ((isTrap) && (words != null)) { + return words.get("message"); + } + return null; + } /** * diff --git a/MikroTikAPI/src/com/eightOceans/mikroTik/ops/AccessListEntry.java b/MikroTikAPI/src/com/eightOceans/mikroTik/ops/AccessListEntry.java index 371dcc4..057be4a 100644 --- a/MikroTikAPI/src/com/eightOceans/mikroTik/ops/AccessListEntry.java +++ b/MikroTikAPI/src/com/eightOceans/mikroTik/ops/AccessListEntry.java @@ -11,26 +11,27 @@ public class AccessListEntry { public static AccessListEntry createWithDefault() { AccessListEntry e = new AccessListEntry(); - e.Authentication = true; - e.Forwarding = true; - e.MinSigStrength = -120; - e.MaxSigStrength = 120; - e.Algo = "aes-ccm"; - e.PrivateKey = Utils.createPrivateWifiKey(); - e.PreSharedKey = Utils.createPresharedWifiKey(12,14,1,2); + e.authentication = true; + e.forwarding = true; + e.minSigStrength = -120; + e.maxSigStrength = 120; + e.algo = "aes-ccm"; + e.privateKey = Utils.createPrivateWifiKey(); + e.preSharedKey = Utils.createPresharedWifiKey(12,14,1,2); return e; } - public String Id; - public String MacAddress; - public int MinSigStrength; - public int MaxSigStrength; - public boolean Forwarding; - public boolean Authentication; - public String Algo; - public String PrivateKey; - public String PreSharedKey; - public String ManagementProtectionKey; - public boolean Disabled; + public String id; + public String comment; + public String macAddress; + public int minSigStrength; + public int maxSigStrength; + public boolean forwarding; + public boolean authentication; + public String algo; + public String privateKey; + public String preSharedKey; + public String managementProtectionKey; + public boolean disabled; } diff --git a/MikroTikAPI/src/com/eightOceans/mikroTik/ops/Wireless.java b/MikroTikAPI/src/com/eightOceans/mikroTik/ops/Wireless.java index 2915b80..463d962 100644 --- a/MikroTikAPI/src/com/eightOceans/mikroTik/ops/Wireless.java +++ b/MikroTikAPI/src/com/eightOceans/mikroTik/ops/Wireless.java @@ -10,7 +10,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; - /** * * @author mh @@ -20,17 +19,63 @@ public class Wireless { private ApiConnection conn; private ExecutorService pool; - protected Wireless(ExecutorService pool, ApiConnection conn) { this.conn = conn; this.pool = pool; } - public Future createOrUpdate(AccessListEntry e) { - return null; - } + return pool.submit(new Callable() { + + @Override + public Result call() throws Exception { + + StringBuilder sb = new StringBuilder(); + sb.append("/interface/wireless/access-list/"); + if ((e.id == null) || ("".equals(e.id))) { + sb.append("add\n"); + } else { + sb.append("set\n"); + } + + sb.append("=comment=" + e.comment + "\n"); + sb.append("=mac-address=" + e.macAddress + "\n"); + + if ((e.id != null) && (!"".equals(e.id))) { + sb.append("=.id=" + e.id + "\n"); + } + sb.append("!done"); + + conn.sendCommand(sb.toString()); + + Result res = new Result(); + ReadDataResult r = conn.readDataSync(); + while (true) { + if (!r.Success) { + res.Success = false; + res.ResultMessage = "AccessList update failed: " + r.ResultMessage; + break; + } else { + MtSentence ms = MtSentence.from(r.Data); + if (ms.isTrap()) { + res.Success = false; + res.ResultMessage = "AccessList update failed, remote sent trap: " + ms.getTrapMsg(); + break; + } else if (ms.isDone()) { + res.Success = true; + break; + } else { + res.Success = false; + res.ResultMessage = "AccessList update failed, remote sent unexpected result"; + } + + } + } + return res; + } + }); + } public Future>> getAccessListEntries() { return pool.submit(new Callable>>() { @@ -76,13 +121,14 @@ public class Wireless { =comment=#GEND0001# Vla */ AccessListEntry ale = AccessListEntry.createWithDefault(); - ale.Algo = ms.getWordAsMap().get("private-algo"); - ale.Authentication = "true".equals(ms.getWordAsMap().get("authentication")); - ale.Disabled = "true".equals(ms.getWordAsMap().get("disabled")); - ale.Forwarding = "true".equals(ms.getWordAsMap().get("forwarding")); - ale.Id = ms.getWordAsMap().get(".id"); - ale.MacAddress = ms.getWordAsMap().get("mac-address"); - ale.ManagementProtectionKey = ms.getWordAsMap().get("management-protection-key"); + ale.comment = ms.getWordAsMap().get("comment"); + ale.algo = ms.getWordAsMap().get("private-algo"); + ale.authentication = "true".equals(ms.getWordAsMap().get("authentication")); + ale.disabled = "true".equals(ms.getWordAsMap().get("disabled")); + ale.forwarding = "true".equals(ms.getWordAsMap().get("forwarding")); + ale.id = ms.getWordAsMap().get(".id"); + ale.macAddress = ms.getWordAsMap().get("mac-address"); + ale.managementProtectionKey = ms.getWordAsMap().get("management-protection-key"); String sigRange = ms.getWordAsMap().get("signal-range"); if (sigRange != null) { String[] parts = sigRange.split("\\.\\."); @@ -92,8 +138,8 @@ public class Wireless { int max = 0; min = Integer.parseInt(parts[0]); max = Integer.parseInt(parts[1]); - ale.MaxSigStrength = max; - ale.MinSigStrength = min; + ale.maxSigStrength = max; + ale.minSigStrength = min; } } catch (NumberFormatException nex) { res.Success = false; @@ -101,16 +147,16 @@ public class Wireless { resLst = null; break; } - } - ale.PreSharedKey = ms.getWordAsMap().get("private-pre-shared-key"); - ale.PrivateKey = ms.getWordAsMap().get("private-key"); + } + ale.preSharedKey = ms.getWordAsMap().get("private-pre-shared-key"); + ale.privateKey = ms.getWordAsMap().get("private-key"); resLst.add(ale); } } } if (resLst != null) { // != null == no failure - resLst.add(AccessListEntry.createWithDefault()); + //resLst.add(AccessListEntry.createWithDefault()); res.Success = true; res.Result = resLst; } @@ -121,5 +167,4 @@ public class Wireless { ); } - } diff --git a/MikroTikAPI/src/com/eightOceans/mikroTik/sample/TestApp.java b/MikroTikAPI/src/com/eightOceans/mikroTik/sample/TestApp.java index 2dfff25..b5e548c 100644 --- a/MikroTikAPI/src/com/eightOceans/mikroTik/sample/TestApp.java +++ b/MikroTikAPI/src/com/eightOceans/mikroTik/sample/TestApp.java @@ -117,8 +117,8 @@ public class TestApp { try { OPs ops = new OPs(conn); Result> r = ops.getWireless().getAccessListEntries().get(); - System.out.println(r.Result.get(0).PreSharedKey); - System.out.println(r.Result.get(0).PrivateKey); + System.out.println(r.Result.get(0).preSharedKey); + System.out.println(r.Result.get(0).privateKey); System.out.println("XXX"); } catch (Throwable th) { th.printStackTrace(); diff --git a/MtWifiUserConfig/config.properties b/MtWifiUserConfig/config.properties index a176f35..862bce9 100644 --- a/MtWifiUserConfig/config.properties +++ b/MtWifiUserConfig/config.properties @@ -3,7 +3,8 @@ AP_1_PORT=8729 AP_1_USER=rcfg AP_1_PWPREF=0a -DEV1=MK Iphone 7 -DEV1_KEY=saldk9012LLada -DEV1_MINDB=-70 +DEV_1=MK Iphone 7 +DEV_1_MAC=01:01:01:01:01:02 +DEV_1_KEY=saldk9012LLada +DEV_1_MINDB=-70 diff --git a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/ApDef.java b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/ApDef.java index d14d3dd..9462e1c 100644 --- a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/ApDef.java +++ b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/ApDef.java @@ -8,7 +8,7 @@ package com.eightOceans.mtWifiUserConfig; public class ApDef { public int index; - public String host; + public String host; public Integer port; public String user; public String pwPrefix; diff --git a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/DevDef.java b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/DevDef.java index d460c1f..2a03100 100644 --- a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/DevDef.java +++ b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/DevDef.java @@ -9,6 +9,7 @@ package com.eightOceans.mtWifiUserConfig; public class DevDef { public int index; public String name; + public String mac; public String preshareKey; public int minDbAllowed; } diff --git a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/Main.java b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/Main.java index 15f9c3c..ba2704f 100644 --- a/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/Main.java +++ b/MtWifiUserConfig/src/com/eightOceans/mtWifiUserConfig/Main.java @@ -3,10 +3,13 @@ package com.eightOceans.mtWifiUserConfig; import com.eightOceans.mikroTik.ApiConnection; import com.eightOceans.mikroTik.Result; import com.eightOceans.mikroTik.SSLMode; +import com.eightOceans.mikroTik.ops.AccessListEntry; +import com.eightOceans.mikroTik.ops.OPs; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -63,9 +66,10 @@ public class Main { if (dev.name == null) { break; } + dev.mac = props.getProperty("DEV_" + i + "_MAC", null); dev.preshareKey = props.getProperty("DEV_" + i + "_KEY", null); if ((dev.preshareKey == null) || (dev.preshareKey.length() < 8)) { - throw new RuntimeException("Preshared key too short!"); + throw new RuntimeException("Preshared key too short. must min 8 chars!"); } String db = props.getProperty("DEV_" + i + "_MINDB", null); if (db != null) { @@ -73,6 +77,7 @@ public class Main { } else { dev.minDbAllowed = -87; } + devs.add(dev); } _currOp = "Getting pw"; @@ -115,6 +120,8 @@ public class Main { CONNECT, LOGIN, + GETENTRIES, + UPDATEENTRIES, FAILED, EXIT, DONE @@ -130,7 +137,9 @@ public class Main { int to = 10; String errMsg = null; ApiConnection conn = new ApiConnection(); + OPs mtOps = new OPs(conn); + List entries = null; CommState cs = CommState.CONNECT; while (cs != CommState.DONE) { @@ -151,12 +160,37 @@ public class Main { setCurrOp("Login to " + ap.host); r = conn.login(ap.user, ap.pwPrefix + remPw).get(to, TimeUnit.SECONDS); if (r.Success) { - cs = cs.EXIT; + cs = cs.GETENTRIES; } else { errMsg = "Login Failed: " + r.ResultMessage; cs = CommState.FAILED; } break; + case GETENTRIES: + setCurrOp("Getting accesslist from " + ap.host); + Result> getRes = mtOps.getWireless().getAccessListEntries().get(to, TimeUnit.SECONDS); + if (getRes.Success) { + entries = getRes.Result; + cs = cs.UPDATEENTRIES; + } else { + errMsg = "Getting access entries failed: " + getRes.ResultMessage; + cs = CommState.FAILED; + } + break; + case UPDATEENTRIES: + List toDel = new ArrayList(); + List toUpd = new ArrayList(); + findChanges(devs, entries, toDel, toUpd); + for (AccessListEntry e : toUpd) { + setCurrOp("Updating '" + e.comment + "' on " + ap.host); + Result uRes = mtOps.getWireless().createOrUpdate(e).get(to, TimeUnit.SECONDS); + if (!uRes.Success) { + System.out.println(".... Update failed:" + uRes.ResultMessage); + } + } + setCurrOp("Updating ended"); + cs = CommState.EXIT; + break; case FAILED: System.out.println(" ! " + (errMsg != null ? errMsg : (_currOp + " Failed")) + "! Skipping this AP"); cs = CommState.EXIT; @@ -178,9 +212,60 @@ public class Main { } } - for (DevDef dev : devs) { + } + + private static void findChanges(List devs, List curr, List toDel, List toUpd) { + + for (AccessListEntry a : curr) { + boolean f = false; + if ((a.comment == null) || (!a.comment.startsWith("#GEND:"))) { + continue; + } + for (DevDef dev : devs) { + if (("#GEND:" + dev.name).equals(a.comment)) { + f = true; + break; + } + } + if (!f) { + toDel.add(a); + } } + for (DevDef dev : devs) { + AccessListEntry t = null; + for (AccessListEntry a : curr) { + if (("#GEND:" + dev.name).equals(a.comment)) { + t = a; + break; + } + } + boolean chg = false; + if (t == null) { + t = AccessListEntry.createWithDefault(); + chg = true; + } + if (!("#GEND:" + dev.name).equals(t.comment)) { + t.comment = "#GEND:" + dev.name; + chg = true; + } + if (!Objects.equals(dev.mac, t.macAddress)) { + t.macAddress = dev.mac; + chg = true; + } + if (dev.minDbAllowed != t.minSigStrength) { + t.minSigStrength = dev.minDbAllowed; + chg = true; + } + if (!Objects.equals(dev.preshareKey, t.preSharedKey)) { + t.preSharedKey = dev.preshareKey; + chg = true; + } + + if (chg) { + toUpd.add(t); + } + } } }