shitty demo for a single reader

This commit is contained in:
Kai Jan Kriegel 2022-03-12 10:46:38 +01:00
parent aa378eec2c
commit 233b9af159
7 changed files with 106 additions and 22 deletions

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "pycapnp"]
path = pycapnp
url = https://github.com/capnproto/pycapnp.git
[submodule "schema"] [submodule "schema"]
path = schema path = schema
url = https://gitlab.com/fabinfra/fabaccess/fabaccess-api url = https://gitlab.com/fabinfra/fabaccess/fabaccess-api

View File

@ -1 +1 @@
from .connect import connect from .connect import connect, connect_with_fabfire_initial, connect_with_fabfire_step

View File

@ -1,11 +1,12 @@
import asyncio import asyncio
import socket import socket
import ssl import ssl
import capnp import capnp
connection_capnp = capnp.load('schema/connection.capnp') connection_capnp = capnp.load('schema/connection.capnp')
authenticationsystem_capnp = capnp.load('schema/authenticationsystem.capnp') authenticationsystem_capnp = capnp.load('schema/authenticationsystem.capnp')
async def myreader(client, reader): async def myreader(client, reader):
while True: while True:
data = await reader.read(4096) data = await reader.read(4096)
@ -18,6 +19,7 @@ async def mywriter(client, writer):
writer.write(data.tobytes()) writer.write(data.tobytes())
await writer.drain() await writer.drain()
async def connect(host, port, user, pw): async def connect(host, port, user, pw):
# Setup SSL context # Setup SSL context
ctx = ssl.create_default_context( ctx = ssl.create_default_context(
@ -55,3 +57,60 @@ async def connect(host, port, user, pw):
else: else:
print("Auth failed") print("Auth failed")
return None return None
async def connect_with_fabfire_initial(host, port, uid):
# Setup SSL context
ctx = ssl.create_default_context(
ssl.Purpose.SERVER_AUTH
)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
# Handle both IPv4 and IPv6 cases
try:
reader, writer = await asyncio.open_connection(
host, port, ssl=ctx, family=socket.AF_INET6
)
except Exception:
reader, writer = await asyncio.open_connection(
host, port, ssl=ctx, family=socket.AF_INET
)
# Start TwoPartyClient using TwoWayPipe (takes no arguments in this mode)
client = capnp.TwoPartyClient()
cap = client.bootstrap().cast_as(connection_capnp.Bootstrap)
# Assemble reader and writer tasks, run in the background
coroutines = [myreader(client, reader), mywriter(client, writer)]
asyncio.gather(*coroutines, return_exceptions=True)
auth = cap.authenticationSystem().authenticationSystem
req = auth.start_request()
req.request.mechanism = "X-FABFIRE"
req.request.initialResponse.initial = uid
rep_prom = req.send()
response = await rep_prom.a_wait()
print(response.response.which())
if response.response.which() == "challence":
print(f"challenge: {response.response.challence}")
return auth, response.response.challence, cap
else:
print(f"Auth failed: {response.response.outcome.result}, additional info: {response.response.outcome.helpText}")
return None
async def connect_with_fabfire_step(auth, msg):
req = auth.step_request()
req.response = msg
rep_prom = req.send()
response = await rep_prom.a_wait()
if response.response.which() == "challence":
print(f"challenge: {response.response.challence}")
return response.response.challence, False # auth cap, challenge, not done
elif response.response.outcome.result == "successful":
print(f"Auth completed successfully! Got additional Data: {response.response.outcome.additionalData.additional}")
return response.response.outcome.additionalData.additional, True # dont care, message, we are done
else:
print(f"Auth failed: {response.response.outcome.result}, additional info: {response.response.outcome.helpText}")
return None

@ -1 +0,0 @@
Subproject commit 5dade41aebcee627ef65e4f3471d7568dcd7a5e2

2
schema

@ -1 +1 @@
Subproject commit c855646a90958ae575d58be074d187acb9f8f4fa Subproject commit 18ed9c2ae6a221f57d19e255165c7ebc4508e9af

44
single.py Normal file
View File

@ -0,0 +1,44 @@
import asyncio
from asyncio_mqtt import Client
import json
import fabapi
async def main():
done = False
cap = None
auth = None
msg = None
async with Client("192.168.178.31") as client:
await client.publish("/cmnd/reader", payload='{"Cmd":"haltPICC"}', qos=2, retain=False)
await client.publish("/cmnd/reader", payload='{"Cmd": "message", "MssgID": 0, "AddnTxt":" Karte auflegen"}', qos=2, retain=False)
async with client.filtered_messages("/rfid_reader/111") as messages:
await client.subscribe("/rfid_reader/#")
async for message in messages:
if not auth:
auth, msg, cap = await fabapi.connect_with_fabfire_initial("192.168.178.31", 59661, message.payload)
elif not done:
msg, done = await fabapi.connect_with_fabfire_step(auth, message.payload)
if done:
await client.publish("/cmnd/reader", payload='{"Cmd":"haltPICC"}', qos=2, retain=False)
ms = await cap.machineSystem().a_wait()
info = await ms.machineSystem.info().a_wait()
ma = await info.info.getMachineURN("urn:fabaccess:resource:Testmachine").a_wait()
if ma.machine.state == "inUse":
await ma.machine.inuse.giveBack().a_wait()
else:
await ma.machine.use.use().a_wait()
done = False
cap = None
auth = None
msg = None
await client.publish("/cmnd/reader", payload=msg, qos=2, retain=False)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

15
test.py
View File

@ -1,15 +0,0 @@
import asyncio
import fabapi
async def main():
boot = await fabapi.connect("localhost", 59661, "Testuser", "secret")
if boot:
ms = await boot.machineSystem().a_wait()
info = await ms.machineSystem.info().a_wait()
ma = await info.info.getMachineURN("urn:fabaccess:resource:Another").a_wait()
print(ma.machine)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())