This release should put us at about half way through the planned work for the networking focus set of releases (0.6.x), a scope roughly defined by the article on A12: Advancing network transparency on the desktop and the one on Arcan as OS design. Alas, it is also the single most difficult and time consuming part left on the entire roadmap.
Before dipping into the major additions and changes, I will break form a little and dwell on what is going on and why.
From the (set of design principles) that we follow; number four “Make State mobile“, five “No State left behind” and six “Privacy fights back” are at the center of attention here.
The idea is to get a protocol which replaces mDNS (local service discovery), SSH (interactive textual shell), X11/VNC/RDP (interactive graphical shell), RTSP (streaming multimedia), HTTP (networked application retrieval and state synchronisation) and a few other lesser knowns, and we are nearly there feature wise.
This is “less” effort than one might think as so much code is needlessly repeated again and again by not leveraging the many bits the designs of these protocols have in common, justified only by legacy and history and not technical and architectural merit.
This is similar to the IPC situation locally that we solve with SHMIF — while others will get to continue to enjoy the cacophony of IPC systems (D-Bus, Wayland, Pipewire, VTxxx, …) where the difficult parts (authentication, discovery, synchronisation, least-privilege separation, zero-copy ownership transfers, queue and resource management, resilience, …) keep on being implemented again and again and again in incompatible ways yet are supposed to work together to solve actual end-user problems — this is the price to pay for being stuck in ‘first order’ forms of reasoning, but simplicity is systemic.
With this protocol as a building block, every single component in Arcan can be de-coupled from one device and re-coupled to running on another – from media parsing and decoding to accelerated rendering and encoding.
To illustrate the point and the self-imposed “grand challenge” — in this photo from one of my labs are the set of user facing devices in the weekly rotation currently capable of running Arcan; each with some quirk or property that makes it interesting to keep in rotation (this is also the least depressing lab, wait until you see the one for displays or the one for input devices).
Together they represent a sort of lighter extreme here:
- The devices that are active should be able to share workload and work ‘ as one ‘.
- Repurposing any device to a ‘one ephemeral task’ runner should be achievable within minutes, and a queue of prepared runners should make activation near instant.
- Installed static state (what it can do) should be known, dynamic state (what you changed) should be extractable.
These tactics should serve to raise the cost for both reliable persistent exploitation and for evading detection considerably. They should also work well for building intuitive and ergonomic compartmentation for harm reduction against both ‘smash and grab’ style attacks, micro-architectural side-channels and against physical theft.
All this across networking infrastructure that is assumed to be unreliable (no global clock), peer-to-peer (no DNS by default) and only accidentally connected to the Internet — what some would call air gapped.
As a refresher, the initial proof of concept – rougly the state in ~2019 – can be seen in this clip:
There will be reason to return to the topic in the near future, but for now, let’s move to the big ticket items for this release. For the both more- and less- detailed list of changes, see the regular Changelog.
Onward to the big ticket items:
The two main tools for using our network protocol are ‘arcan-net’ (standalone) and ‘afsrv_net’ (that transparently maps to script-reachable functions in our Lua scripting layer).
- arcan-net now has the first draft implementation of ‘directory’ mode, which will be used for three purposes; as a discovery rendezvous in WANs where other communication might also be needed (proxying or NAT punching), as a trusted third party state store, and as an arcan appl host.
This part of directory mode covers the arcan appl host setup. It lets any arcan installation share the set of appls it has with any other, and act as a state store (configuration persistence).
There are articles in the queue about the implications of this but as an example out of many — it means I can have an offline ‘build box’ that generates device tailored ‘live’ images (e.g. the hacky scripts in arcan-void-mklive for now); injecting authentication keys into the image and whatever device boots from it can load/restore the same persistent desktop from an otherwise ephemeral read-only environment. The image is logged and attested, and can act as source for comparison against the device at a later date.
For the sake of it, arcan.divergent-desktop.org is currently hosting ‘durden’ and ‘pipeworld‘; subject to me breaking things during daily experimentation. It was started like this:
ARCAN_APPLBASE=./shared ARCAN_STATEPATH=./state arcan-net --directory --soft-auth -l 6680
(the –soft-auth makes it about as insecure as a world of self-signed https, it is unwise to run appls from this server on anything sensitive). In this clip you simply see me connecting to it over a fairly slow link:
The state store bits are less promiscuous and still require an authenticated key exchange. Let’s write a simple arcan appl called ‘demo’:
mkdir demo echo ' function demo() local counter = get_key("counter") or "A" local img = render_text("Hi " .. tostring(counter)) show_image(img, 200) tag_image_transform(img, MASK_OPACITY, function() shutdown() end) store_key("counter", counter .. string.char(string.byte("A") + #counter)) end' > demo/demo.lua
The following clip is the result from me running this appl a few times:
You need to squint a bit, but for each run another letter is attached, walking from ‘A’ and onwards. The point is that this state is managed server-side, had the same public key (== identity) been running on another device, it would have continued where the other last synched :- remote, persistent, observable.
- arcan-net now caches some binary transfers and ramp ups transfers after confirming something is not already in the cache. This is most useful for synching fonts. It also automatically compresses / decompresses binary file transfers.
- afsrv_net has gotten a ‘sweep’ discovery mode, which enumerates the ‘petnames’ in the keystore and periodically tracks which ones that have started- or stopped- responding.
- The protocol now covers role negotiation as part of the initial handshake, where each side can be either Source, Sink or Directory. Pair Source-Source or Sink-Sink will disconnect with an error.
Finally, the protocol itself has added role negotiation as part of the initial handshake. Since both sides can act as either source, sink or directory – we now pair that so trying to connect a source to a source or a sink to a sink would generate error notification.
Our ncurses replacement, arcan-tui, has received a number of fixes in its basic widgets, most notably in its ‘readline’ implementation. The corresponding Lua bindings have also received a lot of attention, and are now suitable for writing most kinds of CLI/TUI applications.
The ‘terminal’ frameserver (afsrv_terminal) that has long acted as our terminal emulator of choice, now has an additional mode of operation (ARCAN_ARG=cli=lua) that we call ‘Lash’ (LuA SHell). This pulls in a Lua VM along with the TUI API bindings, coupled to a simple chainloader script that pulls in a custom shell ruleset from (default) $HOME/.arcan/lash.
The following clip demonstrates some capabilities of a shell written on top of this – “Cat9”.
The reasoning behind all this is covered in a separate article, ‘The Day of a new Command Line Interface: Shell‘ while Cat9 will be getting a more thorough introduction a little later when I am satisfied with its feature set and implementation quality.
A large target for the API/bindings is to quickly build / wrap system services (network device control, file system mounting, …) as frontends to existing tools (wpa_supplicant et al.) that integrate and compose similar to how we illustrated with the tray icon handler.
Arcan splits up its resource handling in a number of static namespaces. The rules behind many of these are quite complex, and really only makes sense when considered as a design to avoid some of the many mistakes in Android and dates back to the old days (2.x+) of that OS, and as preparation for sandboxing resource access in the context of loading appls as shown in the networking section.
In this patch, the configuration database managed through the arcan_db tool can be used to define dynamic user namespaces. A simple example would be:
arcan_db add_appl_kv arcan ns_myhome "Home:rw:/home/me"
Which would allow Arcan instances read/write access to /home/me with the symbolic name “myhome” and the user presentable label as Home. This fits in with the ‘wrapping tools around tui’ point from the lash/TUI section to grant/revoke access to storage as it becomes available.
The ‘catch all’ dependency sponge afsrv_decode (external client with a stricter ruleset on behaviour for tighter sandboxing and privilege separation) that absorbs parsers (one much beloved exploitation target in offensive security) has received basic support for PDFs and similar vector formats via MuPDF.
In the clip below, you can see how the preview feature in the Durden browser HUD spins up a bunch of decode-pdf processes and then toggles to navigate one.
On systems that support the ‘v4l2-loopback’ device interface, the encode will now support exposing its input as a v4l2 device. This means that all the sharing and streaming features can emulate a webcam device for applications that trust such things. The video below shows exposing a window playing back a movie as being treated as a webcam in Chrome: