diff --git a/test/java/foundation/pEp/jniadapter/test/jni153/CTXMultiNode.java b/test/java/foundation/pEp/jniadapter/test/jni153/CTXMultiNode.java new file mode 100644 index 0000000..1f2d99c --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni153/CTXMultiNode.java @@ -0,0 +1,239 @@ +package foundation.pEp.jniadapter.test.jni153; + +import foundation.pEp.jniadapter.Engine; +import foundation.pEp.jniadapter.Message; +import foundation.pEp.jniadapter.decrypt_message_Return; +import foundation.pEp.jniadapter.test.utils.TestCallbacks; +import foundation.pEp.jniadapter.test.utils.model.*; +import foundation.pEp.jniadapter.test.utils.transport.fsmqmanager.FsMQIdentity; +import foundation.pEp.jniadapter.test.utils.transport.fsmqmanager.FsMQManager; +import foundation.pEp.jniadapter.test.utils.transport.fsmqmanager.FsMQMessage; +import foundation.pEp.pitytest.AbstractTestContext; +import foundation.pEp.pitytest.TestContextInterface; + +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.stream.Collectors; + +import static foundation.pEp.pitytest.TestLogger.log; + +public class CTXMultiNode extends AbstractTestContext { + public Engine engine; + public TestCallbacks callbacks; + public Transport transport; + + // Model + public TestModel model; + + // Mappings + private NodeName ownNodeName; + private TestNode ownNode; + public TestIdentity myself; + public TestIdentity partner; + + + CTXMultiNode(NodeName ownNodeName) { + this.ownNodeName = ownNodeName; + } + + @Override + public TestContextInterface init() throws Throwable { + // pEp + callbacks = new TestCallbacks(); + engine = new Engine(); + engine.setMessageToSendCallback(callbacks); + engine.setNotifyHandshakeCallback(callbacks); + + // Model + model = setupModel(); + + // Setup Perspective + ownNode = model.getNode(ownNodeName); + myself = ownNode.getIdent(); + partner = myself.getDefaultPartner(); + + // Transport + // Create own transport identity and Transport + FsMQIdentity transportIdent = myself.getTransportIdent(ownNodeName); + transport = new Transport(transportIdent, model.getAllIdents()); + + return this; + } + + private TestModel setupModel() { + TestModel ret = new TestModel(); + + ret.getNode(NodeName.NODE_A1).setRole(Role.ALICE); + ret.getNode(NodeName.NODE_B1).setRole(Role.BOB); + + ret.getIdent(Role.ALICE).setDefaultPartner(Role.BOB); + ret.getIdent(Role.BOB).setDefaultPartner(Role.ALICE); +// ret.getIdent(Role.CAROL).setDefaultPartner(Role.ALICE); + + return ret; + } + +} + +class Transport { + private FsMQManager fsMQTransport = null; + private EncryptingSenderThread sender = null; + private DecryptingReceiverThread receiver = null; + private FsMQIdentity myself = null; + private List peers = null; + + // Message queues + private LinkedBlockingQueue txQueue = new LinkedBlockingQueue<>(); + private LinkedBlockingQueue rxQueue = new LinkedBlockingQueue<>(); + + public Transport(FsMQIdentity ownIdent, List peers) { + this.myself = ownIdent; + this.peers = peers; + this.sender = new EncryptingSenderThread(this, txQueue); + this.receiver = new DecryptingReceiverThread(this, rxQueue); + this.fsMQTransport = new FsMQManager(ownIdent); + + for (TestIdentity ti : peers) { + fsMQTransport.identities.addAll(ti.getAllTransportIdents()); + } + } + + public void clearOwnQueue() { + fsMQTransport.clearOwnQueue(); + } + + public boolean canReceiveAsync() { + return !rxQueue.isEmpty(); + } + + public void sendAsync(Message msg) { + txQueue.add(msg); + } + + public Message receiveAsyncNonBlocking() { + return rxQueue.remove(); + } + + public void sendRaw(String pEpAddress, String msg) { + //Find identity for address + List res = peers.stream().filter(i -> { + return i.pEpIdent.address.equals(pEpAddress); + }).collect(Collectors.toList()); + + if (res.size() > 1) { + throw new RuntimeException("Unknown Error"); + } else if (res.size() <= 0) { + throw new RuntimeException("Unknown address"); + } + TestIdentity id = res.get(0); + + for (FsMQIdentity tID : id.getAllTransportIdents()) { + fsMQTransport.sendMessage(tID.getAddress(), msg); +// log("send() to: " + tID.getAddress()); + } + } + + public String receiveRaw() { + FsMQMessage rx = fsMQTransport.receiveMessage(2000); + return rx.getMsg(); + } + + public void start() { + sender.start(); + receiver.start(); + } +} + + +class EncryptingSenderThread extends Thread { + private Engine engine = null; + private Transport transport = null; + private LinkedBlockingQueue queue; + + public EncryptingSenderThread(Transport transport, LinkedBlockingQueue queue) { + this.transport = transport; + this.queue = queue; + } + + @Override + public void run() { + engine = new Engine(); + Message msg; + String msgEnc; + while (true) { + try { + msg = queue.take(); + if (msg.getTo().size() != 1) { + throw new RuntimeException("Sorry, msg.To has to have exactly 1 receiver for now"); + } + String to = msg.getTo().get(0).address; + msgEnc = encryptMessage(msg); + transport.sendRaw(to, msgEnc); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public String encryptMessage(Message msg) { + String longMessage = msg.getLongmsg(); + + Message msgEnc = engine.encrypt_message(msg, null, Message.EncFormat.PEP); + String encFormat; + String transportMsg; + if (msgEnc != null) { + encFormat = "CRYPT"; + transportMsg = msgEnc.encodeMIME(); + } else { + encFormat = "PLAIN"; + transportMsg = msg.encodeMIME(); + } + log("<- : [" + encFormat + "] - " + longMessage); + return transportMsg; + } +} + + +class DecryptingReceiverThread extends Thread { + private Engine engine = null; + private Transport transport = null; + private LinkedBlockingQueue queue; + + public DecryptingReceiverThread(Transport transport, LinkedBlockingQueue queue) { + this.transport = transport; + this.queue = queue; + } + + @Override + public void run() { + engine = new Engine(); + String msg; + Message msgDec; + while (true) { + msg = transport.receiveRaw(); + msgDec = decryptMessage(msg); + try { + queue.put(msgDec); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private Message decryptMessage(String msg) { + Message msgIn = new Message(msg); + Message msgInDec = null; + + decrypt_message_Return decRet = engine.decrypt_message(msgIn, null, 0); + + msgInDec = decRet.dst; + + String encFormat = "PLAIN"; + if (!msgIn.getLongmsg().equals(msgInDec.getLongmsg())) { + encFormat = "CRYPT"; + } + + log("-> : [" + encFormat + "] - " + msgInDec.getLongmsg()); + return msgInDec; + } +} \ No newline at end of file diff --git a/test/java/foundation/pEp/jniadapter/test/jni153/Makefile b/test/java/foundation/pEp/jniadapter/test/jni153/Makefile new file mode 100644 index 0000000..34409e7 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni153/Makefile @@ -0,0 +1,46 @@ +include ../../../../../../../Makefile.conf +include ../Makefile.conf + +TEST_UNIT_NAME=jni153 + +JAVA_CLASSES+= \ + TestAlice.class \ + TestBob.class \ + CTXMultiNode.class + +.PHONY: pitytest compile alice bob test clean + +all: both compile + +pitytest: + $(MAKE) -C $(PITYTEST_DIR) + +both: + $(MAKE) bob& + $(MAKE) alice + +alice: compile clean-pep-home-alice + cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR_ALICE) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestAlice + +bob: compile clean-pep-home-bob + cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR_BOB) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).TestBob + +compile: $(JAVA_CLASSES) pitytest + +%.class: %.java + cd $(JAVA_CWD);$(JAVAC_CMD) -cp $(CLASSPATH) $(JAVA_PKG_BASEPATH)/$(TEST_UNIT_NAME)/$< + +clean: + rm -f $(JAVA_CLASSES) + rm -f *.class + rm -f *.log + rm -Rf .gnupg + rm -Rf .lldb + +clean-pep-home: clean-pep-home-alice clean-pep-home-bob + +clean-pep-home-alice: + rm -rf $(PEP_HOME_DIR_ALICE)/.pEp + +clean-pep-home-bob: + rm -rf $(PEP_HOME_DIR_BOB)/.pEp diff --git a/test/java/foundation/pEp/jniadapter/test/jni153/TestAlice.java b/test/java/foundation/pEp/jniadapter/test/jni153/TestAlice.java new file mode 100644 index 0000000..ae7f378 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni153/TestAlice.java @@ -0,0 +1,43 @@ +package foundation.pEp.jniadapter.test.jni153; + +import foundation.pEp.jniadapter.Message; +import foundation.pEp.jniadapter.test.utils.AdapterTestUtils; +import foundation.pEp.jniadapter.test.utils.model.NodeName; +import foundation.pEp.pitytest.TestSuite; +import foundation.pEp.pitytest.TestUnit; +import foundation.pEp.pitytest.utils.TestUtils; + +import static foundation.pEp.pitytest.TestLogger.log; + + +class TestAlice { + public static void main(String[] args) throws Exception { + TestSuite.getDefault().setVerbose(true); + TestSuite.getDefault().setTestColor(TestUtils.TermColor.GREEN); + + CTXMultiNode JNI153Ctx = new CTXMultiNode(NodeName.NODE_A1); + + new TestUnit("test", JNI153Ctx, ctx -> { + ctx.transport.clearOwnQueue(); + ctx.myself.pEpIdent = ctx.engine.myself(ctx.myself.pEpIdent); + log(AdapterTestUtils.identityToString(ctx.myself.pEpIdent, true)); + + ctx.transport.start(); + + ctx.transport.sendAsync(AdapterTestUtils.newOutMessage(ctx.myself.pEpIdent, ctx.partner.pEpIdent, "UNIQUE_" + String.valueOf(0))); + int counter = 0; + + while (true) { + while (ctx.transport.canReceiveAsync()) { + ctx.transport.sendAsync(AdapterTestUtils.newOutMessage(ctx.myself.pEpIdent, ctx.partner.pEpIdent, "UNIQUE_" + String.valueOf(counter))); + Message msg = ctx.transport.receiveAsyncNonBlocking(); + counter++; + } + } + }); + + TestSuite.getDefault().run(); + } +} + + diff --git a/test/java/foundation/pEp/jniadapter/test/jni153/TestBob.java b/test/java/foundation/pEp/jniadapter/test/jni153/TestBob.java new file mode 100644 index 0000000..773f2fc --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/jni153/TestBob.java @@ -0,0 +1,56 @@ +package foundation.pEp.jniadapter.test.jni153; + +import foundation.pEp.jniadapter.Engine; +import foundation.pEp.jniadapter.Message; +import foundation.pEp.jniadapter.test.utils.AdapterTestUtils; +import foundation.pEp.jniadapter.test.utils.model.NodeName; +import foundation.pEp.pitytest.TestSuite; +import foundation.pEp.pitytest.TestUnit; +import foundation.pEp.pitytest.utils.TestUtils; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static foundation.pEp.pitytest.TestLogger.log; + +class TestBob { + public static void main(String[] args) throws Exception { + TestSuite.getDefault().setVerbose(true); + TestSuite.getDefault().setTestColor(TestUtils.TermColor.YELLOW); + + CTXMultiNode JNI153Ctx = new CTXMultiNode(NodeName.NODE_B1); + + new TestUnit("test", JNI153Ctx, ctx -> { + ExecutorService executorService = Executors.newFixedThreadPool(10); + ctx.transport.clearOwnQueue(); + ctx.myself.pEpIdent = ctx.engine.myself(ctx.myself.pEpIdent); + log(AdapterTestUtils.identityToString(ctx.myself.pEpIdent, true)); + + ctx.transport.start(); + + int counter = 0; + while (true) { + + while (ctx.transport.canReceiveAsync()) { + Message msgRx = ctx.transport.receiveAsyncNonBlocking(); + log(AdapterTestUtils.identityToString(msgRx.getFrom(),true)); + ctx.transport.sendAsync(AdapterTestUtils.newOutMessage(ctx.myself.pEpIdent, msgRx.getFrom(), msgRx.getLongmsg() + " - ACK")); + counter++; + + if (counter % 4 == 0) { + executorService.submit(() -> { + Engine eng = new Engine(); + log("Mistrusting"); + eng.keyMistrusted(msgRx.getFrom()); + + }); + } + } + } + }); + + TestSuite.getDefault().run(); + } + + +} diff --git a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java index 3fa3e08..bf058b0 100644 --- a/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java +++ b/test/java/foundation/pEp/jniadapter/test/utils/AdapterTestUtils.java @@ -338,6 +338,30 @@ public class AdapterTestUtils { return msg; } + public static Message newOutMessage(Identity from, Identity to, String longMessage) { + Message ret = new Message(); + Vector toList = new Vector<>(); + toList.add(to); + ret.setTo(toList); + ret.setFrom(from); +// ret.setShortmsg(); + ret.setLongmsg(longMessage); + ret.setDir(Message.Direction.Outgoing); + return ret; + } + +// public static Message newInMessage(Identity from, Identity to, String longMessage) { +// Message ret = new Message(); +// Vector toList = new Vector<>(); +// toList.add(to); +// ret.setTo(toList); +// ret.setFrom(from); +//// ret.setShortmsg(); +// ret.setLongmsg(longMessage); +// ret.setDir(Message.Direction.Outgoing); +// return ret; +// } + public static Message generateSourceMessage(Identity from, Identity to, long id, long longMsgLen) { Message msg = new Message(); Vector vID = new Vector();