Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4374
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/CHANGELOG b/CHANGELOG
index 299efa9..1281629 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,32 +1,34 @@
Copyright (C) 2022 LANNOCC (Shawn A. Wilson)
@%@~LICENSE:MIT~@%@
+saw_070922_2 - Remove Python-3.8 syntax magic so we can run on 3.7 (raspbian).
+
saw_070922_1 - Move database "name" constants into their own file.
saw_070822_2 - Make sure we don't create db unless we start a node master.
saw_070822_1 - Implement ListLabels, LabelsList, LabelInterest, and LabelIgnore.
saw_070722_1 - Peers are now able to sign on to the nodes.
saw_070622_3 - Implement re-registration. Fix a security concern for
registration... this will invalidate existing signed entries.
Implement proper signature verification on nodes.
saw_070622_2 - Fix error with register command.
saw_070622_1 - Much work implementiong node protocol v2 and proper node-based
registration.
saw_062622_1 - Implementation of peer protocol v1 (basic) and v2 (encrypted).
saw_061722_1 - Beginning crypto handler v1 (label registration).
saw_061622_1 - Beginning node protocol v1 (ping-pong).
saw_061422_3 - Use os.makedirs() for the user_data_dir (creates parents).
saw_061422_2 - Now have a simple `lank` command.
saw_061422_1 - Initial commit (barebones pip project skeleton).
diff --git a/lank/__version__.py b/lank/__version__.py
index 1dd4e65..1e4e9b3 100644
--- a/lank/__version__.py
+++ b/lank/__version__.py
@@ -1,2 +1,2 @@
-__version__ = '0.4.1'
+__version__ = '0.4.2'
diff --git a/lank/node/protocol/v1/__init__.py b/lank/node/protocol/v1/__init__.py
index c0bebce..354b942 100644
--- a/lank/node/protocol/v1/__init__.py
+++ b/lank/node/protocol/v1/__init__.py
@@ -1,63 +1,67 @@
from .. import Handler as Base
from .message import Ping, Pong
from bidict import bidict
class Handler(Base):
VERSION = 1
BYTE_ORDER = 'big'
ID_SIZE = 1 # bytes
MSG_BY_ID = bidict({
1: Ping,
2: Pong,
})
def client(self, master):
raise NotImplementedError()
def server(self, master):
- while msg := self.s_recv():
+ #while msg := self.s_recv():
+ msg = self.s_recv()
+ while msg:
reply = None
if isinstance(msg, Ping):
reply = Pong(msg.nonce)
else:
raise ValueError(f'unhandled message: {msg}')
if reply:
self.s_send(reply)
+ msg = self.s_recv()
+
def send(self, msg):
self.sock.sendall(self.get_id_bytes(msg))
msg.send(self)
def recv(self):
id_bytes = self.recv_bytes(self.ID_SIZE)
if id_bytes is None: return None
msg = self.get_msg_type(id_bytes)
return msg.recv(self)
def get_id_bytes(self, msg):
try:
mid = self.MSG_BY_ID.inverse[type(msg)]
try:
return mid.to_bytes(self.ID_SIZE, self.BYTE_ORDER)
except OverflowError as e:
raise ValueError(f'msg type id too big: {mid}') from e
except KeyError as e:
raise ValueError(f'unsupported message type: {type(msg)}') from e
def get_msg_type(self, id_bytes):
mid = int.from_bytes(id_bytes, self.BYTE_ORDER)
try:
return self.MSG_BY_ID[mid]
except KeyError as e:
raise ValueError(f'unsupported message type id: {mid}') from e
diff --git a/lank/node/protocol/v2/__init__.py b/lank/node/protocol/v2/__init__.py
index 061d638..f4d82d9 100644
--- a/lank/node/protocol/v2/__init__.py
+++ b/lank/node/protocol/v2/__init__.py
@@ -1,613 +1,621 @@
from ..v1 import Handler as Base
from .. import KEEPALIVE, MAX_TIME_SKEW
from .ack import *
from .sync import *
from .peer import *
from .register import *
from .deny import *
from lank.crypto import get_handler as get_crypto
from bidict import bidict
from gevent import socket
from datetime import datetime, timedelta
from uuid import UUID
class Handler(Base):
VERSION = 2
BUFFER_SIZE = 8192
ENCODING = 'utf-8'
SYNC_MARGIN = 10 * 60 # seconds
MSG_BY_ID = bidict({
1: Ping,
2: Pong,
3: NodeOn,
4: NodeIsSelf,
5: NodeAlreadyConnected,
6: NodeTimeSkewed,
7: NodeIsIsolated,
8: NodesOnly,
9: Reservation,
10: ReservationRequired,
11: ReservationCancel,
12: Registration,
13: ReRegistration,
14: RegistrationSuccess,
15: GetRegistration,
16: LabelNotFound,
17: Signed,
18: SignedUUIDNotFound,
19: SignedLabelMismatch,
20: SignedNameMismatch,
21: SignatureFailure,
22: PeerOn,
23: PeerAlreadyConnected,
24: ListLabels,
25: LabelsList,
26: LabelInterest,
27: LabelIgnore,
})
def client(self, master):
self.node_uuid = None
self.peer_label = None
sync = master.ldb.get_last_signed_created()
if sync:
sync = datetime.fromisoformat(sync)
sync -= timedelta(seconds=self.SYNC_MARGIN)
msg = NodeOn(master.now(), master.uuid, sync)
self.c_send(msg)
reply = self.c_recv()
if not reply: return
if isinstance(reply, Denial):
raise KeyError(reply.__class__.__name__)
elif not isinstance(reply, NodeOn):
raise ValueError('expecting NodeOn reply')
elif reply.uuid == master.uuid:
raise KeyError(NodeIsSelf.__name__)
elif reply.nonce != msg.nonce:
raise ValueError('nonce mismatch')
elif reply.uuid in master.nodes_by_uuid:
raise ValueError('node already connected (uuid match)')
elif not reply.check_time_skew(master.now(), MAX_TIME_SKEW):
raise ValueError('time skew')
self.node_uuid = reply.uuid
self.sync_signed(master, self.c_send, sync, reply)
master.nodes_by_uuid[self.node_uuid] = self
master.status()
try:
self.sock.settimeout(KEEPALIVE)
ping = None
while msg:
try:
- while msg := self.c_recv():
+ #while msg := self.c_recv():
+ msg = self.c_recv()
+ while msg:
reply = None
if isinstance(msg, Pong):
if not ping:
raise ValueError('pong without ping')
elif msg.nonce != ping.nonce:
raise ValueError('nonce mismatch')
ping = None
elif isinstance(msg, Reservation):
reply = self.reservation(master, msg)
elif isinstance(msg, ReservationCancel):
self.reservation_cancel(master, msg)
elif isinstance(msg, GetRegistration):
reply = self.get_registration(master, msg)
elif isinstance(msg, Signed):
reply = self.signed(master, msg)
else:
raise ValueError('unhandled message')
if reply:
self.c_send(reply)
if isinstance(reply, Denial):
msg = None
break
+ msg = self.c_recv()
+
except socket.timeout as e:
if ping: raise e
ping = Ping()
self.c_send(ping)
finally:
del master.nodes_by_uuid[self.node_uuid]
master.status()
def server(self, master):
self.node_uuid = None
self.peer_label = None
try:
- while msg := self.s_recv():
+ #while msg := self.s_recv():
+ msg = self.s_recv()
+ while msg:
reply = None
if isinstance(msg, Ping):
reply = Pong(msg.nonce)
elif isinstance(msg, NodeOn):
reply = self.node_on(master, msg)
elif isinstance(msg, Reservation):
reply = self.reservation(master, msg)
elif isinstance(msg, ReservationCancel):
self.reservation_cancel(master, msg)
elif isinstance(msg, Registration):
if isinstance(msg, ReRegistration):
reply = self.reregistration(master, msg)
else:
reply = self.registration(master, msg)
elif isinstance(msg, GetRegistration):
reply = self.get_registration(master, msg)
elif isinstance(msg, Signed):
reply = self.signed(master, msg)
elif isinstance(msg, PeerOn):
reply = self.peer_on(master, msg)
elif isinstance(msg, ListLabels):
reply = self.list_labels(master, msg)
elif isinstance(msg, LabelInterest):
reply = self.label_interest(master, msg)
elif isinstance(msg, LabelIgnore):
reply = self.label_ignore(master, msg)
else:
raise ValueError('unhandled message')
if reply:
self.s_send(reply)
if isinstance(reply, Denial):
break
+ msg = self.s_recv()
+
finally:
if self.node_uuid:
del master.nodes_by_uuid[self.node_uuid]
master.status()
if self.peer_label:
del master.peers_by_label[self.peer_label]
master.status()
def send(self, msg):
id_bytes = self.get_id_bytes(msg)
data = msg.to_bytes(self)
self.sock.sendall(id_bytes + (data if data else b''))
def node_on(self, master, msg):
assert isinstance(msg, NodeOn)
if self.node_uuid:
return NodeAlreadyConnected()
if self.peer_label:
return PeerAlreadyConnected()
if msg.uuid == master.uuid:
return NodeIsSelf()
if msg.uuid in master.nodes_by_uuid:
return NodeAlreadyConnected()
if not msg.check_time_skew(master.now(), MAX_TIME_SKEW):
return NodeTimeSkewed()
self.node_uuid = msg.uuid
sync = master.ldb.get_last_signed_created()
if sync:
sync = datetime.fromisoformat(sync)
sync -= timedelta(seconds=self.SYNC_MARGIN)
self.s_send(NodeOn(master.now(), master.uuid, sync,
msg.nonce))
self.sync_signed(master, self.s_send, sync, msg)
master.nodes_by_uuid[self.node_uuid] = self
master.status()
return None
def reservation(self, master, msg):
assert isinstance(msg, Reservation)
reply = None
if not master.nodes_by_uuid:
reply = NodeIsIsolated()
elif msg.label in master.reservations:
reservation = master.reservations[msg.label]
res_uuid = reservation[0]
if msg.uuid != res_uuid: # collision
reply = ReservationCancel(msg.label)
master.broadcast_nodes(reply, skip=self)
del master.reservations[msg.label]
else: # just an echo from another node?
pass
elif master.ldb.get_label_by_name(msg.label):
reply = ReservationCancel(msg.label, True)
else:
reservation = (msg.uuid, self.sock, master.now())
master.reservations[msg.label] = reservation
master.broadcast_nodes(msg, skip=self)
if not self.node_uuid: reply = msg
return reply
def reservation_cancel(self, master, msg):
assert isinstance(msg, ReservationCancel)
if msg.label in master.reservations:
master.broadcast_nodes(msg, skip=self)
del master.reservations[msg.label]
def registration(self, master, msg):
assert isinstance(msg, Registration)
if not master.nodes_by_uuid:
return NodeIsIsolated()
if msg.label not in master.reservations:
return ReservationRequired(msg.label)
reservation = master.reservations[msg.label]
res_uuid = reservation[0]
res_sock = reservation[1]
if res_sock != self.sock: # imposter
return ReservationRequired(msg.label)
if res_uuid != msg.uuid: # imposter
return ReservationRequired(msg.label)
crypto = get_crypto(msg.version)
pub_key = crypto.load_public_key(msg.key_pair_pem)
data = crypto.get_register_message(msg.label, msg.time_nonce)
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
label_id = None
addr = str(msg.key_pair_pem, crypto.ENCODING)
with master.ldb.Transaction():
label_id = master.ldb.insert_label(msg.label)
time = master.now()
master.ldb.insert_signed(str(msg.uuid), label_id,
master.ldb.NAME_REGISTER, msg.time_nonce, addr,
msg.signature, msg.version, str(master.uuid), time)
master.signed_recently[res_uuid] = time
del master.reservations[msg.label]
master.labels_by_id[label_id] = msg.label
master.broadcast_nodes(Signed(
msg.version,
res_uuid,
msg.label,
master.ldb.NAME_REGISTER,
msg.time_nonce,
addr,
msg.signature,
master.uuid,
time
), skip=self)
return RegistrationSuccess(res_uuid)
def reregistration(self, master, msg):
assert isinstance(msg, ReRegistration)
if not master.nodes_by_uuid:
return NodeIsIsolated()
signed = master.ldb.get_signed_by_uuid(str(msg.ref_uuid))
if not signed:
return SignedUUIDNotFound(msg.ref_uuid)
if master.labels_by_id[signed['label']] != msg.label:
return SignedLabelMismatch(msg.ref_uuid, msg.label)
if signed['name'] != master.ldb.NAME_REGISTER:
return SignedNameMismatch(msg.ref_uuid, master.ldb.NAME_REGISTER)
crypto = get_crypto(signed['version'])
pub_key = crypto.load_public_key(
signed['address'].encode(crypto.ENCODING))
data = crypto.get_reregister_message(signed['key'], signed['uuid'],
msg.key_pair_pem)
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
key = f'M:{msg.ref_uuid}'
addr = str(msg.key_pair_pem, crypto.ENCODING)
with master.ldb.Transaction():
time = master.now()
master.ldb.insert_signed(str(msg.uuid), signed['label'],
master.ldb.NAME_REGISTER, key, addr,
msg.signature, msg.version, str(master.uuid), time)
master.signed_recently[msg.uuid] = time
master.broadcast_nodes(Signed(
msg.version,
msg.uuid,
msg.label,
master.ldb.NAME_REGISTER,
key,
addr,
msg.signature,
master.uuid,
time
), skip=self)
return RegistrationSuccess(msg.uuid)
def get_registration(self, master, msg):
assert isinstance(msg, GetRegistration)
if msg.label not in master.labels_by_id.inverse:
return LabelNotFound(msg.label)
label_id = master.labels_by_id.inverse[msg.label]
signed = master.ldb.find_signed_by_label_name(label_id,
master.ldb.NAME_REGISTER,
limit=1)
assert signed
assert len(signed)==1
signed = signed[0]
crypto = get_crypto(signed['version'])
return Registration(
UUID(signed['uuid']),
msg.label,
signed['version'],
signed['key'],
signed['address'].encode(crypto.ENCODING),
signed['signature'])
def signed(self, master, msg):
assert isinstance(msg, Signed)
if not self.node_uuid:
return NodesOnly()
if msg.uuid in master.signed_recently:
return None
exists = master.ldb.get_signed_by_uuid(str(msg.uuid))
if exists:
return None
crypto = get_crypto(msg.version)
if msg.name == master.ldb.NAME_REGISTER:
if msg.key.startswith('M:'): # re-register (ref uuid)
ref_uuid = msg.key[2:]
signed = master.ldb.get_signed_by_uuid(ref_uuid)
if not signed:
raise KeyError(f'signed uuid ref not found: {ref_uuid}')
if master.labels_by_id[signed['label']] != msg.label:
raise KeyError(f'signed label mismatch: {msg.label}')
if signed['name'] != master.ldb.NAME_REGISTER:
raise KeyError(f'signed name mismatch: {signed["name"]}')
pub_key = crypto.load_public_key(
signed['address'].encode(crypto.ENCODING))
data = crypto.get_reregister_message(signed['key'],
signed['uuid'], msg.address.encode(crypto.ENCODING))
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
else: # initial registration (time_nonce)
pub_key = crypto.load_public_key(
msg.address.encode(crypto.ENCODING))
data = crypto.get_register_message(msg.label, msg.key)
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
elif msg.name == master.ldb.NAME_PEER:
if msg.label not in master.labels_by_id.inverse:
return LabelNotFound(msg.label)
label_id = master.labels_by_id.inverse[msg.label]
signed = master.ldb.find_signed_by_label_name(label_id,
master.ldb.NAME_REGISTER,
limit=1)
assert signed
assert len(signed)==1
signed = signed[0]
pub_key = crypto.load_public_key(
signed['address'].encode(crypto.ENCODING))
host = msg.address[:msg.address.index(':')]
port = int(msg.address[msg.address.index(':')+1:])
data = PeerOn._to_sign_(crypto, msg.uuid, msg.label, host, port)
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
else:
raise ValueError(f'unsupported signed name id: {msg.name}')
label_id = None
with master.ldb.Transaction():
try:
label_id = master.labels_by_id.inverse[msg.label]
except KeyError:
label_id = master.ldb.insert_label(msg.label)
master.ldb.insert_signed(str(msg.uuid), label_id, msg.name, msg.key,
msg.address, msg.signature, msg.version,
str(msg.node_uuid),
msg._to_datetime_(msg.timestamp))
if label_id not in master.labels_by_id:
master.labels_by_id[label_id] = msg.label
if msg.label in master.reservations:
del master.reservations[msg.label]
master.signed_recently[msg.uuid] = master.now()
master.broadcast_nodes(msg, skip=self)
return None
def sync_signed(self, master, send, sync, msg):
assert isinstance(msg, NodeOn)
msg_sync = msg._to_datetime_(msg.synced) \
if msg.synced else None
if sync and (not msg_sync or msg_sync < sync):
if not msg_sync:
signed_list = master.ldb.list_signed()
else:
signed_list = master.ldb.find_signed_since(msg_sync)
for signed in signed_list:
send(Signed(
signed['version'],
UUID(signed['uuid']),
master.labels_by_id[signed['label']],
signed['name'],
signed['key'],
signed['address'],
signed['signature'],
UUID(signed['node_uuid']),
signed['created']
))
#sync = ldb.get_last_signed_created()
#if sync:
# sync = datetime.fromisoformat(sync)
# sync -= timedelta(seconds=self.SYNC_MARGIN)
#reply = NodeOn(master.now(), master.uuid, sync,
# msg.nonce)
def peer_on(self, master, msg):
assert isinstance(msg, PeerOn)
if self.peer_label:
# FIXME: maybe allow this?
# (e.g. peer switching identity or multiple-login)
return PeerAlreadyConnected()
if self.node_uuid:
return NodeAlreadyConnected()
if not master.nodes_by_uuid:
return NodeIsIsolated()
try:
label_id = master.labels_by_id.inverse[msg.label]
except KeyError:
return LabelNotFound(msg.label)
signed = master.ldb.find_signed_by_label_name(label_id,
master.ldb.NAME_REGISTER,
limit=1)
assert signed
assert len(signed)==1
signed = signed[0]
crypto = get_crypto(msg.version)
key_pair_pem = signed['address'].encode(crypto.ENCODING)
pub_key = crypto.load_public_key(key_pair_pem)
data = msg.to_sign(crypto)
if not crypto.verify(pub_key, data, msg.signature):
return SignatureFailure(msg.uuid)
assert ':' not in self.addr[0]
key = f'{self.addr[0]}:{self.addr[1]}'
assert ':' not in msg.host
addr = f'{msg.host}:{msg.port}'
with master.ldb.Transaction():
time = master.now()
master.ldb.insert_signed(str(msg.uuid), label_id,
master.ldb.NAME_PEER, key, addr,
msg.signature, msg.version, str(master.uuid), time)
master.signed_recently[msg.uuid] = time
self.peer_label = msg.label
master.peers_by_label[self.peer_label] = self
master.status()
reply = Signed(
msg.version,
msg.uuid,
msg.label,
master.ldb.NAME_PEER,
key,
addr,
msg.signature,
master.uuid,
time
)
master.broadcast_nodes(reply, skip=self)
return reply
def list_labels(self, master, msg):
assert isinstance(msg, ListLabels)
return LabelsList(master.labels_by_id.values())
def label_interest(self, master, msg):
assert isinstance(msg, LabelInterest)
master.add_label_interest(msg.label, self)
def label_ignore(self, master, msg):
assert isinstance(msg, LabelIgnore)
master.remove_label_interest(msg.label, self)
diff --git a/lank/peer/protocol/v1/__init__.py b/lank/peer/protocol/v1/__init__.py
index f5736c5..b2cfa28 100644
--- a/lank/peer/protocol/v1/__init__.py
+++ b/lank/peer/protocol/v1/__init__.py
@@ -1,62 +1,66 @@
from .. import Handler as Base
from .message import Ping, Pong
from bidict import bidict
class Handler(Base):
VERSION = 1
BYTE_ORDER = 'big'
ID_SIZE = 1 # bytes
MSG_BY_ID = bidict({
1: Ping,
2: Pong,
})
def server(self, master):
- while msg := self.recv():
+ #while msg := self.recv():
+ msg = self.recv()
+ while msg:
print(f' {self.addr} -> {msg}')
reply = None
if isinstance(msg, Ping):
reply = Pong(msg.nonce)
else:
raise ValueError(f'unhandled message: {msg}')
if reply:
print(f' {self.addr} <- {reply}')
self.send(reply)
+ msg = self.recv()
+
def send(self, msg):
self.sock.sendall(self.get_id_bytes(msg))
msg.send(self)
def recv(self):
id_bytes = self.recv_bytes(self.ID_SIZE)
if id_bytes is None: return None
msg = self.get_msg_type(id_bytes)
return msg.recv(self)
def get_id_bytes(self, msg):
try:
mid = self.MSG_BY_ID.inverse[type(msg)]
try:
return mid.to_bytes(self.ID_SIZE, self.BYTE_ORDER)
except OverflowError as e:
raise ValueError(f'msg type id too big: {mid}') from e
except KeyError as e:
raise ValueError(f'unsupported message type: {type(msg)}') from e
def get_msg_type(self, id_bytes):
mid = int.from_bytes(id_bytes, self.BYTE_ORDER)
try:
return self.MSG_BY_ID[mid]
except KeyError as e:
raise ValueError(f'unsupported message type id: {mid}') from e
diff --git a/lank/peer/protocol/v2/__init__.py b/lank/peer/protocol/v2/__init__.py
index 7baf982..358dab9 100644
--- a/lank/peer/protocol/v2/__init__.py
+++ b/lank/peer/protocol/v2/__init__.py
@@ -1,106 +1,110 @@
from ..v1 import Handler as Base
from .ack import *
from .media import *
from bidict import bidict
class Handler(Base):
VERSION = 2
ENCODING = 'utf-8'
BUFFER_SIZE = 2048 # bytes
CRYPTO_SIG_SIZE = 512 # bytes
CRYPTO_SIZE_SIZE = 3 # bytes
MSG_BY_ID = bidict({
1: Ping,
2: Pong,
3: Text,
})
def __init__(self, sock, addr, crypto, priv_key, pub_key=None):
super().__init__(sock, addr)
self.crypto = crypto
self.priv_key = priv_key
self.pub_key = pub_key
self.label = None
def server(self, master):
- while msg := self.recv():
+ #while msg := self.recv():
+ msg = self.recv()
+ while msg:
print(f' {self.addr} -> {msg}')
reply = None
if isinstance(msg, Ping):
reply = Pong(msg.nonce)
elif isinstance(msg, Text):
#reply = Text('got your message')
pass
else:
raise ValueError(f'unhandled message: {msg}')
if reply:
print(f' {self.addr} <- {reply}')
self.send(reply)
+ msg = self.recv()
+
def send(self, msg):
id_bytes = self.get_id_bytes(msg)
data = msg.to_bytes(self)
data = self.crypto.encrypt(self.pub_key,
id_bytes + (data if data else b''))
sig = self.crypto.sign(self.priv_key, data)
assert len(sig) == self.CRYPTO_SIG_SIZE
size_bytes = len(data).to_bytes(self.CRYPTO_SIZE_SIZE, self.BYTE_ORDER)
self.sock.sendall(sig + size_bytes + data)
def recv(self):
sig = self.recv_bytes(self.CRYPTO_SIG_SIZE)
if not sig: return None
sig = bytes(sig)
crypto_size = self.recv_bytes(self.CRYPTO_SIZE_SIZE)
if not crypto_size: return None
crypto_size = int.from_bytes(crypto_size, self.BYTE_ORDER)
if not crypto_size: return None
data = self.recv_bytes(crypto_size)
if not data: return None
data = bytes(data)
verify = (data, sig)
data = self.crypto.decrypt(self.priv_key, data)
msg = self.get_msg_type(data[:self.ID_SIZE])
data = data[self.ID_SIZE:]
if not issubclass(msg, Ping):
if not self.pub_key:
raise ValueError(f'have signed message but no key to check')
if not self.crypto.verify(self.pub_key, verify[0], verify[1]):
raise ValueError(f'signature verification failed')
msg = msg.from_bytes(self, data)
if isinstance(msg, Ping):
if msg.label != self.label:
self.pub_key = self.crypto.get_public_key(msg.label)
if not self.pub_key:
raise ValueError(f'no key on file for label: {msg.label}')
self.label = msg.label
print(f' {self.addr} is {self.label}')
if not self.crypto.verify(self.pub_key, verify[0], verify[1]):
raise ValueError(f'signature verification failed')
return msg
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Sep 14, 9:40 AM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3616
Default Alt Text
(29 KB)
Attached To
Mode
rLANK Encrypted Communications
Attached
Detach File
Event Timeline
Log In to Comment