Subject: Thoughts on flexible mesh-routing of NNCP packets

From: John Goerzen <[email-masked]>
Date: Sun, 31 Jan 2021 01:03:59 -0600

Hi,

So I've been thinking about the problem of getting NNCP packets 
delivered in a dynamic topology.  As they are source-routed, that 
can be a bit of a challenge.  I've got some ideas.

First I want to make sure I understand how the onion routing in 
NNCP works, because I think it's somewhat different than Tor (not 
trying to preserve the anonymity of the sender).  Is this 
description correct?  (I originally posted this in comp.mail.uucp 
and will correct it there if not)

In this example, node1 is wanting to send a packet to node5 via 
intermediaries.

So what happens here is that node1 first generates an encrypted 
packet to node5,
using node5's public key, and that packet is signed by node1. 
Next, it takes
that whole thing, encryption and signature and all, and uses it as 
input for an
encrypted packet to node4 -- that packet itself also signed by 
node1. It
repeats this process until it generates the packet to node2.

Think of it like this:

node1$ gpg --sign -e -r node5 < datafile > node5.gpg
node1$ gpg --sign -e -r node4 < node5.gpg > node4.gpg
node1$ gpg --sign -e -r node3 < node4.gpg > node3.gpg
node1$ gpg --sign -e -r node2 < node3.gpg > outbound-to-node2.gpg
node1$ rm node

Node2 receives the packet - encrypted only to it, and signed by 
node1 -
and decrypts the payload. The payload is a command (send this on 
to
node2) and an encrypted payload for THAT command - encrypted to 
node2
and signed by node1. This process also continues until you get to 
node5.
So, at node4, node4 receives its packet from node3 -- signed by 
node1, encrypted
to node4. Node4 decrypts it and finds a payload for node5 -- 
again, signed by
node1, encrypted to node5. It places this in the queue for node5. 
(Just like
with node2)

Node5 receives the packet. It verifies the signature from node1, 
and it is the
only node that can decrypt it. nncp-toss finds the packet in the 
rx queue from
node4, but it doesn't really pass this information on anywhere; it 
knows from
the signature that the origin was node1 (doesn't much care how it 
arrived) and
that single verified signature is what is used for all processing 
(looking up
whether node1 is authorized to run a command, exposed as an 
environment variable
to nncp-exec runners, used to determine the incoming directory for 
nncp-file,
etc).

Node5 could sort of know that the packet arrived from node4, but 
there is no
cryptographic guarantee of that (the ONLY signatures in this whole 
chain come
from node1) so that information is basically discarded.

This is different from the UUCP model, in which node5 only really 
knows about
its neighbor node4 and may have no idea whatever about node1's 
existence.
Permissions in UUCP are based on what the neighbor can do, not 
what the source
can do, if I remember correctly.

The other thing that follows from this is that if node3 were 
compromised, the
worst it can do is fail to relay packets. It cannot modify packets 
(signature
validation from node1 would fail), it cannot spoof node1 (lacking 
its private
key), it can't inject fake packets claiming to have followed the
node1!node2!node3 path (again, lacking node1's private key), it 
can't even see
what the ultimate destination is (it just knows the next hop is 
node4 but since
it doesn't have node4's private key, it doesn't even know if node4 
is the
ultimate hop or not).

Now then....

If that is correct, that would imply that it would be difficult 
to, say, bypass node2 on the way to node5 -- though it would be 
(theoretically) easy enough to send from node1 to node1.5 and then 
on to node2.

So I've been thinking about this more expansively.

https://verbnetworks.com/research/store-forward-networks/ planted 
the idea in my head: why not use Syncthing for this?

It would seem to make perfect sense, given nncp-xfer.  There could 
be a shared Syncthing folder which leaf sites could dump packets 
into using nncp-xfer, and read other packets out (also using 
nncp-xfer).  Since Syncthing implements a Bittorrent-like 
protocol, a leaf site can just dump packets into its local 
Syncthing folder, letting Syncthing get them out via whatever path 
it can.  Once the files are properly received, the receiver 
deletes them and this propagates out over the swarm as well. 
Slick!

I had initially been thinking up some fancy scheme to send back a 
"I've got this packet, delete your copy" back to the originator, 
but then realized Syncthing basically already solved that.

- John