⑨ lab ≡ ByteLabs

Plan9/Vnc

— Igor Böhm

How to connect from Plan9 to MacOS using vnc

⑨ lab ≡ 9front VNC screencast…

term% @{ramfs ; cd /tmp ; hget https://9lab.org/vid/plan9/vnc.mp4 > vnc.mp4 && treason vnc.mp4}

The above screencast was recorded on 9front Community vs. Infrastructure using wrec running on a Lenovo T420s featuring the program vncv that is used to log into a remote MacOS Big Sur system using the VNC Protocol (i.e. VNC).

The default vnc can not connect to MacOS Big Sur:

term% vncv steve.9lab.home
vncv: authentication failure: unknown auth type 0x51e2124

This issue has been resolved on 9front vnc in patch. If you do not use 9front the following patch should resolve the connection issue:

term% cat cmd.vnc.auth.c.patch
From: Igor Böhm <igor@9lab dot org>
Date: Wed, 22 Sep 2021 06:36:54 +0000
Subject: [PATCH] vnc: enable connecting to Darwin


Tested on MacOS Catalina and Big Sur releases.
---
diff 61f37abf576a02c7f1e3561cfaba3c0457f55c9d de22c9e5d93042f458a1e6c4b7f8ef97c1f68c2a
--- a/sys/src/cmd/vnc/auth.c	Fri Aug 27 16:13:11 2021
+++ b/sys/src/cmd/vnc/auth.c	Wed Sep 22 08:36:54 2021
@@ -33,6 +33,8 @@
 		v->vers = 37;
 	else if(strncmp(msg, "RFB 003.008\n", VerLen) == 0)
 		v->vers = 38;
+	else if(strncmp(msg, "RFB 003.889\n", VerLen) == 0)
+		v->vers = 38;  /* Darwin */
 	else /* RFC6143: Any other should be treated as 3.3. */
 		v->vers = 33;

Simply git/import the above patch and rebuild vnc:

% bind -ac /dist/plan9front /
% git/branch -n feature/vnc-darwin-patch
refs/heads/feature/vnc-darwin-patch: 61f37abf576a02c7f1e3561cfaba3c0457f55c9d
% git/import cmd.vnc.auth.c.patch
applying vnc: enable connecting to Darwin
M sys/src/cmd/vnc/auth.c
% cd /sys/src/cmd/vnc
% mk install
  …
% mk clean

NOTE that the above applied the patch in a branch (feature/vnc-darwin-patch). You could also import the patch onto the front main development branch.

Next, run ipso in a new window, adding an entry to factotum for authentication to work automatically. Here a sample entry:

key proto=vnc server=steve.9lab.home !password=St3v3J0bS?

Before you can get started there is one crucial setting that you have make on MacOS:

⑨ lab ≡ 9front Darwin Screen Sharing System Setting…

MacOS - Screen Sharing System Setting: Check VNC viewers may control screen with password…

Finally, this is how to start a VNC connection via vncv to a MacOS system:

% vncv steve.9lab.home

And here is the above screencast on youtube:

Copy and Paste

Copy and Paste between steve (i.e. Darwin) and front (i.e. Plan9) via VNC does not work. Howbeit, it is attainable to accomplish Snarf and Paste via a combination of ssh and drawterm. The idea is to connect from front to steve using ssh and open a drawterm connection back to front, exporting /dev/snarf as well as /mnt/term (i.e. effectively exposing steve’s file system to front).

Connect from front to steve via ssh:

# ssh:front ⇒ ssh:steve
front% vt -bx ssh steve.9lab.home
…
steve%

Open drawterm connection from steve to front:

# drawterm:steve ⇒ drawterm:front
steve% drawterm -G -h front.9lab.home
…
front%

Serve steve’s file system (e.g. /mnt/term) and its snarf buffer (e.g. /dev/snarf):

front% cat bin/rc/serve
#!/bin/rc
rfork e
switch($#*){
case 1
	m=$1
case *
	echo usage: serve hostname
	exit usage
}
# export /mnt/term (i.e. file system)
srvfs $m.$user     /mnt/term
# export /dev (i.e. snarf buffer)
srvfs $m.$user.dev /dev
front% bin/rc/srvdt darwin

Next, steve’s file system and snarf buffer are imported (i.e. mounted) into a lifted namespace, thereby exposing them in the current session:

front% cat bin/rc/import
#!/bin/rc
rfork e
for(m in (steve)){
	if(test ! -e /n/$m/Users && test -e /srv/$m.$user)
		plumb 'Local mount /srv/'$m'.'$user' /n/'$m''
	if(test ! -e /n/$m.dev/snarf && test -e /srv/$m.$user.dev)
		plumb 'Local mount /srv/'$m'.'$user'.dev /n/'$m'.dev'
}
front% bin/rc/import
…

Note that this namespace lifting “trick” relies on the following setup in $home/lib/profile:

front% cat $home/lib/profile
…
switch($service){
case terminal
	auth/factotum
	webcookies
	webfs
	# -- namespace lifting
	srvfs plumbspace.$user.$pid /n
	plumber
	rfork n
	mount -b /srv/plumbspace.$user.$pid /n
	# --
	prompt=('term% ' '	')
…

At this stage it ought to be possible to snarf from steve via:

front% cat bin/rc/rsnarf
#!/bin/rc
rfork e
if(~ $remote '')
	echo $0' failed: - define remote (e.g. remote=steve)'
if(test -e /n/$remote.dev/snarf)
	cat /dev/snarf > /n/$remote.dev/snarf
front% remote=steve
front% bin/rc/rsnarf

To propagate (i.e. paste front snarf buffer) the clipboard to steve:

front% cat bin/rc/rpaste
#!/bin/rc
rfork e
if(~ $remote '')
	echo $0' failed: - define remote (e.g. remote=darwin)'
if(test -e /n/$remote.dev/snarf)
	cat /n/$remote.dev/snarf
front% remote=darwin
front% bin/rc/rpaste
☺

One option to mimick a remote clipboard is to fire up an acme instance with rsnarf and rpaste available via middle-clicking in a tag of an acme window. To simplify injecting commands into an acme tag-line the following is helpful:

front% cat bin/rc/a/tag/snarf.tag
(rsnarf)→$remote | (<rpaste)←$remote | (Edit ,d)
…
front% cat bin/rc/a/tag/snarf
#!/bin/rc
echo >/mnt/acme/$winid/tag
cat /bin/a/tag/snarf.tag >/mnt/acme/$winid/tag

Opening an acme window acting as a remote clipboard is accomplished via:

front% cat bin/rc/rclipboard
#!/bin/rc
rfork n
fn Help{
  echo `{basename $0}^' remote (e.g. steve|tim)'
}
fn Clipboard{
  R=$1
  L='clipboard.'^$R
  echo $L
  Label $L
  if (test -e /mnt/plumb/edit)
  	bind /dev/null /mnt/plumb/edit
  if (test -e /mnt/term/mnt/plumb/edit)
  	bind /dev/null /mnt/term/mnt/plumb/edit
  ramfs
  cd /tmp
  remote=$R
  touch $L
  acme -c1 $L
}
switch ($#*) {
	case 0
		Help
	case *
		Clipboard $1
}
front% rclipboard steve
… (type a/tag/snarf and middle-click it)
⑨ lab ≡ VNC session with *acme* style clipboard…

⑨ lab ≡ VNC session with acme style clipboard

#Plan9 #9front