Changes to enable basic reading/creating/updating accesslist-entries on an AP

This commit is contained in:
Michael Hoess 2015-08-19 21:38:34 +01:00
parent 63f74c67ba
commit 88f3594d5f
8 changed files with 187 additions and 48 deletions

View File

@ -26,7 +26,7 @@ public class MtSentence {
break; break;
} else if (w.contains("!trap")) { } else if (w.contains("!trap")) {
s.isTrap = true; s.isTrap = true;
break; //break;
} else if (w.contains("!re")) { } else if (w.contains("!re")) {
} else if (w.startsWith("=")) { } else if (w.startsWith("=")) {
@ -42,7 +42,7 @@ public class MtSentence {
} }
if ((!s.isDone) && (!s.isTrap)) { if ((!s.isDone) /*&& (!s.isTrap)*/) {
s.words = newWords; s.words = newWords;
} }
return s; return s;
@ -63,6 +63,12 @@ public class MtSentence {
return isTrap; return isTrap;
} }
public String getTrapMsg() {
if ((isTrap) && (words != null)) {
return words.get("message");
}
return null;
}
/** /**
* *

View File

@ -11,26 +11,27 @@ public class AccessListEntry {
public static AccessListEntry createWithDefault() { public static AccessListEntry createWithDefault() {
AccessListEntry e = new AccessListEntry(); AccessListEntry e = new AccessListEntry();
e.Authentication = true; e.authentication = true;
e.Forwarding = true; e.forwarding = true;
e.MinSigStrength = -120; e.minSigStrength = -120;
e.MaxSigStrength = 120; e.maxSigStrength = 120;
e.Algo = "aes-ccm"; e.algo = "aes-ccm";
e.PrivateKey = Utils.createPrivateWifiKey(); e.privateKey = Utils.createPrivateWifiKey();
e.PreSharedKey = Utils.createPresharedWifiKey(12,14,1,2); e.preSharedKey = Utils.createPresharedWifiKey(12,14,1,2);
return e; return e;
} }
public String Id; public String id;
public String MacAddress; public String comment;
public int MinSigStrength; public String macAddress;
public int MaxSigStrength; public int minSigStrength;
public boolean Forwarding; public int maxSigStrength;
public boolean Authentication; public boolean forwarding;
public String Algo; public boolean authentication;
public String PrivateKey; public String algo;
public String PreSharedKey; public String privateKey;
public String ManagementProtectionKey; public String preSharedKey;
public boolean Disabled; public String managementProtectionKey;
public boolean disabled;
} }

View File

@ -10,7 +10,6 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
/** /**
* *
* @author mh * @author mh
@ -20,17 +19,63 @@ public class Wireless {
private ApiConnection conn; private ApiConnection conn;
private ExecutorService pool; private ExecutorService pool;
protected Wireless(ExecutorService pool, ApiConnection conn) { protected Wireless(ExecutorService pool, ApiConnection conn) {
this.conn = conn; this.conn = conn;
this.pool = pool; this.pool = pool;
} }
public Future<Result> createOrUpdate(AccessListEntry e) { public Future<Result> createOrUpdate(AccessListEntry e) {
return null;
return pool.submit(new Callable<Result>() {
@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<Result<List<AccessListEntry>>> getAccessListEntries() { public Future<Result<List<AccessListEntry>>> getAccessListEntries() {
return pool.submit(new Callable<Result<List<AccessListEntry>>>() { return pool.submit(new Callable<Result<List<AccessListEntry>>>() {
@ -76,13 +121,14 @@ public class Wireless {
=comment=#GEND0001# Vla =comment=#GEND0001# Vla
*/ */
AccessListEntry ale = AccessListEntry.createWithDefault(); AccessListEntry ale = AccessListEntry.createWithDefault();
ale.Algo = ms.getWordAsMap().get("private-algo"); ale.comment = ms.getWordAsMap().get("comment");
ale.Authentication = "true".equals(ms.getWordAsMap().get("authentication")); ale.algo = ms.getWordAsMap().get("private-algo");
ale.Disabled = "true".equals(ms.getWordAsMap().get("disabled")); ale.authentication = "true".equals(ms.getWordAsMap().get("authentication"));
ale.Forwarding = "true".equals(ms.getWordAsMap().get("forwarding")); ale.disabled = "true".equals(ms.getWordAsMap().get("disabled"));
ale.Id = ms.getWordAsMap().get(".id"); ale.forwarding = "true".equals(ms.getWordAsMap().get("forwarding"));
ale.MacAddress = ms.getWordAsMap().get("mac-address"); ale.id = ms.getWordAsMap().get(".id");
ale.ManagementProtectionKey = ms.getWordAsMap().get("management-protection-key"); ale.macAddress = ms.getWordAsMap().get("mac-address");
ale.managementProtectionKey = ms.getWordAsMap().get("management-protection-key");
String sigRange = ms.getWordAsMap().get("signal-range"); String sigRange = ms.getWordAsMap().get("signal-range");
if (sigRange != null) { if (sigRange != null) {
String[] parts = sigRange.split("\\.\\."); String[] parts = sigRange.split("\\.\\.");
@ -92,8 +138,8 @@ public class Wireless {
int max = 0; int max = 0;
min = Integer.parseInt(parts[0]); min = Integer.parseInt(parts[0]);
max = Integer.parseInt(parts[1]); max = Integer.parseInt(parts[1]);
ale.MaxSigStrength = max; ale.maxSigStrength = max;
ale.MinSigStrength = min; ale.minSigStrength = min;
} }
} catch (NumberFormatException nex) { } catch (NumberFormatException nex) {
res.Success = false; res.Success = false;
@ -102,15 +148,15 @@ public class Wireless {
break; break;
} }
} }
ale.PreSharedKey = ms.getWordAsMap().get("private-pre-shared-key"); ale.preSharedKey = ms.getWordAsMap().get("private-pre-shared-key");
ale.PrivateKey = ms.getWordAsMap().get("private-key"); ale.privateKey = ms.getWordAsMap().get("private-key");
resLst.add(ale); resLst.add(ale);
} }
} }
} }
if (resLst != null) { // != null == no failure if (resLst != null) { // != null == no failure
resLst.add(AccessListEntry.createWithDefault()); //resLst.add(AccessListEntry.createWithDefault());
res.Success = true; res.Success = true;
res.Result = resLst; res.Result = resLst;
} }
@ -121,5 +167,4 @@ public class Wireless {
); );
} }
} }

View File

@ -117,8 +117,8 @@ public class TestApp {
try { try {
OPs ops = new OPs(conn); OPs ops = new OPs(conn);
Result<List<AccessListEntry>> r = ops.getWireless().getAccessListEntries().get(); Result<List<AccessListEntry>> r = ops.getWireless().getAccessListEntries().get();
System.out.println(r.Result.get(0).PreSharedKey); System.out.println(r.Result.get(0).preSharedKey);
System.out.println(r.Result.get(0).PrivateKey); System.out.println(r.Result.get(0).privateKey);
System.out.println("XXX"); System.out.println("XXX");
} catch (Throwable th) { } catch (Throwable th) {
th.printStackTrace(); th.printStackTrace();

View File

@ -3,7 +3,8 @@ AP_1_PORT=8729
AP_1_USER=rcfg AP_1_USER=rcfg
AP_1_PWPREF=0a AP_1_PWPREF=0a
DEV1=MK Iphone 7 DEV_1=MK Iphone 7
DEV1_KEY=saldk9012LLada DEV_1_MAC=01:01:01:01:01:02
DEV1_MINDB=-70 DEV_1_KEY=saldk9012LLada
DEV_1_MINDB=-70

View File

@ -9,6 +9,7 @@ package com.eightOceans.mtWifiUserConfig;
public class DevDef { public class DevDef {
public int index; public int index;
public String name; public String name;
public String mac;
public String preshareKey; public String preshareKey;
public int minDbAllowed; public int minDbAllowed;
} }

View File

@ -3,10 +3,13 @@ package com.eightOceans.mtWifiUserConfig;
import com.eightOceans.mikroTik.ApiConnection; import com.eightOceans.mikroTik.ApiConnection;
import com.eightOceans.mikroTik.Result; import com.eightOceans.mikroTik.Result;
import com.eightOceans.mikroTik.SSLMode; import com.eightOceans.mikroTik.SSLMode;
import com.eightOceans.mikroTik.ops.AccessListEntry;
import com.eightOceans.mikroTik.ops.OPs;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -63,9 +66,10 @@ public class Main {
if (dev.name == null) { if (dev.name == null) {
break; break;
} }
dev.mac = props.getProperty("DEV_" + i + "_MAC", null);
dev.preshareKey = props.getProperty("DEV_" + i + "_KEY", null); dev.preshareKey = props.getProperty("DEV_" + i + "_KEY", null);
if ((dev.preshareKey == null) || (dev.preshareKey.length() < 8)) { 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); String db = props.getProperty("DEV_" + i + "_MINDB", null);
if (db != null) { if (db != null) {
@ -73,6 +77,7 @@ public class Main {
} else { } else {
dev.minDbAllowed = -87; dev.minDbAllowed = -87;
} }
devs.add(dev);
} }
_currOp = "Getting pw"; _currOp = "Getting pw";
@ -115,6 +120,8 @@ public class Main {
CONNECT, CONNECT,
LOGIN, LOGIN,
GETENTRIES,
UPDATEENTRIES,
FAILED, FAILED,
EXIT, EXIT,
DONE DONE
@ -130,7 +137,9 @@ public class Main {
int to = 10; int to = 10;
String errMsg = null; String errMsg = null;
ApiConnection conn = new ApiConnection(); ApiConnection conn = new ApiConnection();
OPs mtOps = new OPs(conn);
List<AccessListEntry> entries = null;
CommState cs = CommState.CONNECT; CommState cs = CommState.CONNECT;
while (cs != CommState.DONE) { while (cs != CommState.DONE) {
@ -151,12 +160,37 @@ public class Main {
setCurrOp("Login to " + ap.host); setCurrOp("Login to " + ap.host);
r = conn.login(ap.user, ap.pwPrefix + remPw).get(to, TimeUnit.SECONDS); r = conn.login(ap.user, ap.pwPrefix + remPw).get(to, TimeUnit.SECONDS);
if (r.Success) { if (r.Success) {
cs = cs.EXIT; cs = cs.GETENTRIES;
} else { } else {
errMsg = "Login Failed: " + r.ResultMessage; errMsg = "Login Failed: " + r.ResultMessage;
cs = CommState.FAILED; cs = CommState.FAILED;
} }
break; break;
case GETENTRIES:
setCurrOp("Getting accesslist from " + ap.host);
Result<List<AccessListEntry>> 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<AccessListEntry> toDel = new ArrayList();
List<AccessListEntry> 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: case FAILED:
System.out.println(" ! " + (errMsg != null ? errMsg : (_currOp + " Failed")) + "! Skipping this AP"); System.out.println(" ! " + (errMsg != null ? errMsg : (_currOp + " Failed")) + "! Skipping this AP");
cs = CommState.EXIT; cs = CommState.EXIT;
@ -178,9 +212,60 @@ public class Main {
} }
} }
for (DevDef dev : devs) {
} }
private static void findChanges(List<DevDef> devs, List<AccessListEntry> curr, List<AccessListEntry> toDel, List<AccessListEntry> 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);
}
}
} }
} }