Logo address

Drawterm

2021/09/27

What is Drawterm?

昔はコマンドのリモート実行と言えば telnet であったが、現在ではセキュリティの問題によって使われていない。安全な環境なら、使っても構わないのだが、使えるようにするためには(サーバー側の)特別の設定が必要になる。

現在では telnet に代わって、 unix の相互環境では ssh が、Plan9 の相互環境では cpu が使われている。unix から Plan9 へは drawterm が、Plan9 から unix へは ssh が標準的な方法である。

drawterm は、 unix から Plan9 にアクセスするための、 unix 用の ツールである。ssh と異なりグラフィク端末を実現している。また cpu コマンドと同様に、クライアントのファイルシステムをリモート側にマウントする。

図1: drawterm によって見える Plan9 ホスト

現在 drawterm には2つの系列が存在する。1つは drawterm の作者 Russ の直系のもの(以下これを drawterm_russ とする) 、他は drawterm_russ から派生した Cinap のもの(以下これを drawterm_cinap とする)。Russ は現在は drawterm に直接は携わっていない。drawterm を GitHUB に上げ[1]、運営を任せている。運営はバグ修正が中心である。他方 drawterm_cinap は Cinap が改良を継続している[2]。

Russ のホームページ[3]には drawterm について

Copyright © 2021 Plan 9 Foundation
Portions Copyright © 2005 Russ Cox, MIT
とある。他方 Plan9 の配布ファイルに含まれている、この部分は
Copyright (c) 2005 Lucent Technologies
Portions Copyright (c) 2005 Russ Cox, MIT
となっている。Lucent Technologies は当時の Bell-Labs の親会社である。
つまり Russ は drawterm のすべてを書いた訳ではない。Russ は Bell-Labs の誰かが途中まで書いた drawterm を完成させたのである。この「誰か」とは Ken Thompson であると断定できる根拠がある。(あとで説明する)

[1] https://github.com/9fans/drawterm
[2] http://drawterm.9front.org
[3] https://swtch.com/drawterm/

Installation

compile

僕の MacBook はもう古くなっている:
macOS Sierra (10.12.1)
Xcode: Version 9.2
従って、新しい MacBook で同じ結果になるかどうか、確認できない。

ここでのコンパイルは次のようにやればよい:

CONF=osx-x11 make
多くの警告が出るが、エラーにはならずに終了する。

README を読めば、他の OS でのコンパイル方法が判る。2021 年現在では

-rw-r--r--  1 arisawa  arisawa     1330 Aug 14 12:39 Make.android
-rw-r--r--  1 arisawa  arisawa      664 Aug 14 12:39 Make.android-386
-rw-r--r--  1 arisawa  arisawa      679 Aug 14 12:39 Make.android-amd64
-rw-r--r--  1 arisawa  arisawa      690 Aug 14 12:39 Make.android-arm
-rw-r--r--  1 arisawa  arisawa      687 Aug 14 12:39 Make.android-arm64
-rw-r--r--  1 arisawa  arisawa       40 Aug 14 12:39 Make.config
-rw-r--r--  1 arisawa  arisawa      460 Aug 14 12:39 Make.dragonfly
-rw-r--r--  1 arisawa  arisawa      472 Aug 14 12:39 Make.fbdev
-rw-r--r--  1 arisawa  arisawa      457 Aug 14 12:39 Make.freebsd
-rw-r--r--  1 arisawa  arisawa      493 Aug 14 12:39 Make.irix
-rw-r--r--  1 arisawa  arisawa      398 Aug 14 12:39 Make.linux386
-rw-r--r--  1 arisawa  arisawa      512 Aug 14 12:39 Make.netbsd
-rw-r--r--  1 arisawa  arisawa      491 Aug 14 12:39 Make.openbsd
-rw-r--r--  1 arisawa  arisawa      414 Aug 14 12:39 Make.osx
-rw-r--r--  1 arisawa  arisawa      404 Aug 14 12:39 Make.osx-cocoa
-rw-r--r--  1 arisawa  arisawa      443 Aug 14 12:39 Make.osx-x11
-rw-r--r--  1 arisawa  arisawa      421 Aug 14 12:39 Make.pthread
-rw-r--r--  1 arisawa  arisawa      377 Aug 14 12:39 Make.sun
-rw-r--r--  1 arisawa  arisawa      527 Aug 14 12:39 Make.unix
-rw-r--r--  1 arisawa  arisawa      855 Aug 14 12:39 Make.win32
-rw-r--r--  1 arisawa  arisawa     1160 Aug 14 12:39 Makefile
であるから、これからサポート状況が判る。例えば
CONF=freebsd make
とすればよい。

5年前(2016)にはこんなに多くのメニューはなかった。実際この部分は

-rw-r--r-- 1 arisawa arisawa    40  7月  4 12:23 Make.config
-rw-r--r-- 1 arisawa arisawa   493  7月  4 12:23 Make.irix
-rw-r--r-- 1 arisawa arisawa   414  7月  4 12:23 Make.osx
-rw-r--r-- 1 arisawa arisawa   426  7月  4 12:23 Make.osx-x11
-rw-r--r-- 1 arisawa arisawa   421  7月  4 12:23 Make.pthread
-rw-r--r-- 1 arisawa arisawa   377  7月  4 12:23 Make.sun
-rw-r--r-- 1 arisawa arisawa   485  7月  4 12:23 Make.unix
-rw-r--r-- 1 arisawa arisawa   826  7月  4 12:23 Make.win32
-rw-r--r-- 1 arisawa arisawa  1165  7月  4 12:23 Makefile
に過ぎなかった。サポートが広がったのかと言えば、そうではない。世の中、gcc から clang に移行しつつあり、そのために OS ごとにどちらを使うか、細かく指定しなければならなくなっている。

setting

drawterm を使いやすくするために、環境変数を定義しておいたほうが便利である。
Russ のも Cinap のも、共に
cpu=XXX # cpu server
auth=YYY # auth server
の2つを定義する。

Russ のと Cinap には重要な違いがある。
Russ のはサーバー名を名前で与えることができる。しかし、Cinap の drawterm は名前解決に手間取っており、IP アドレスで与えた方が良い。(そうしないと使い物にならない)

Cinap の drawterm に対する Russ の drawterm の優位性は Plan9port との相性にあると考えてよい。

Execution

graphic drawterm

コマンド

drawterm
を実行する。

factotum を利用していない場合には、ホストのパスワードが求められる。
立ち上がってしまうと、ホストをリモートから操れる。ホストを直接いじっているのと、操作感はほとんど違わない。unix ホストを ssh を通じて使っているのと雲泥の差である。またホストと端末の間でも copy&paste ができるのが素晴らしい1

なお、copy&paste の際には3ボタンマウスの中央ボタンが重要な役割を演じる。しかし現在では3ボタンマウスは手に入り難い。そのかわりに中央のホイールを押さえれば中央ボタンの代わりになっている。しかし、これが硬くて使い難いものがあるんだね...
Cinap の drawterm では SHIFT キーを押しながらマウスの右ボタンをクリックすると中央ボタンの代わりになっている。硬いホイールのマウスを持っている場合には重宝する。

どちらの drawterm も、日本語の文字変換はできない。drawterm の設計は、端末のキーボードのアウトプットを直接サーバーに送るようになっている。日本語の文字を含む文書をサーバー側に作りたい場合には、端末側にテキストファイルを開いて、そこで文章を作り、それを copy&paste でホスト側に送ることになる。特に drawterm 上での直接変換をしなくても、慣れた端末側で日本語の文章を作るほうがよほど効率が良いかも知れない。

drawterm のコマンドシンタックスは、drawterm_russ の場合

usage: drawterm [-c host] [-u user] [-a authserver] [-s secstore]
drawterm_cinap の場合
usage: drawterm [-GBO] [-h host] [-u user] [-a authserver] [-s secstore] [-e 'crypt hash'] [-k keypattern] [-p] [-t timeout] [-r root] [-g geometry] [-c cmd ...]
ホストを指定する部分が "-c host" から "-h host" に変更されている。これは drawterm_cinap ではホストで実行するコマンド
[-c cmd ...]
を指定できるようなったことによる変更である。9front の cpu コマンドは
cpu [ -p ] [ -h server ] [ -u user ] [ -a auth-method ] [ -P patternfile ] [ -e encryption-hash-algs ] [ -k keypattern ] [ -c cmd args ... ]
である。僕の手元には Plan9 ver.3 のマニュアルがあるが、それによると当時の cpu コマンドのシンタックスは
cpu [ -h server ] [ -f ] [ -a auth-method ] [ -e encryption-hash-algs ] [ -c cmd args ... ]
である。また伝統的な Plan9 を保守しているサイトが存在し[1]、そこにおいても cpu コマンドのシンタックスは 9front と大差ない。つまり drawterm_cinap は cpu コマンドにシンタックスを合わせたのである。

マウスを使ってリモートホストを操作することは必ずしも良いことばかりではない。僕は drawterm からグラフィックスを外したコマンドが欲しいと思っていたが、drawterm_cinap はそれを実現している。"-G" フラグがそれである。特に

-c cmd ...
を使った場合、グラフィックスは邪魔にしかならない。

/mnt/term より下にクライアントのファイルシステムが見える。Mac の場合

hebe% ls -l /mnt/term
...
d-rwxrwxr-x M 8509 arisawa arisawa  6426 Aug 21 06:02 /mnt/term/Applications
d-rwxrwxr-x M 8509 arisawa arisawa   544 Sep  2  2013 /mnt/term/Developer
d-rwxrwxr-x M 8509 arisawa arisawa   408 Aug 20  2017 '/mnt/term/Incompatible Software'
d-rwxr-xr-x M 8509 arisawa arisawa  2720 Dec 10  2019 /mnt/term/Library
d-rwxr-xr-x M 8509 arisawa arisawa   102 Sep  2  2013 /mnt/term/Local
d-rwxr-xr-x M 8509 arisawa arisawa    68 Aug 20  2017 /mnt/term/Network
d-rwxr-xr-x M 8509 arisawa arisawa   136 Apr 20  2020 /mnt/term/System
d-rwxrwxr-x M 8509 arisawa arisawa   578 Nov 18  2014 '/mnt/term/User Guides and Information'
d-rwxr-xr-x M 8509 arisawa arisawa   272 Aug 20  2017 /mnt/term/Users
...
となっている。drawterm では /mnt/term を通じて、ホストとクライアントの間でファイルのコピーなどの操作が可能である。例えば慣れた cp コマンドで、ホストとクライアントのファイルのやりとりができる。それだけではなく、ホスト側のツールがそのまま使えるのが凄い。

drawterm_russ の場合には、ここの "arisawa" の部分は "unknown" と表示されている。本来は "root" である。どうすべきかはいろいろな議論があり得る。これは異質のファイルをマウントしたときに発生する共通の問題であり、深い議論が必要なところで、決定的な答えは出しにくい。この問題に関して後にまた議論する。


注 1. drawterm_russ にはバグがあって、ホスト端末間の copy&paste は日本語の文字を含むばあいにはできない。drawterm_cinap は問題なし

none graphic drawterm

drawterm_cinap には drawterm を ssh のように使うフラグがある。もちろんマウスを使ってホストを操作することはできないし acme も使えない。しかし簡単な処理を行うのに適している。そこで僕は次のようなコマンド cpu を定義している。

cpu

#!/usr/local/plan9/bin/rc
if(~ $USER ?* && ~ $cpu ?* && ~ $auth ?*){
	xdrawterm -GBO -p $*
	exit
}
echo examine your env variable:
echo USER $USER
echo cpu $cpu
echo auth $auth
Plan9port の rc で書かれているが、行われていることは簡単で、環境変数 USER,cpu,auth が定義されていれば
xdrawterm -GBO -p $*
を実行し、定義されていなければ、定義を促しているだけである。
xdrawterm とは drawterm_cinap のことで、僕は drawterm_russ を drawterm としている。

"-GBO" としているのは、僕は drawterm を家庭内の LAN の中だけで使っているので、セキュリティのレベルを落として Plan9port に合わせているからである。

mbook$ cpu
arisawa@local p9sk1 password:
cpu: failed to chdir to '/Users/arisawa/dist/drawterm-cinap-2021b'
hebe% pwd
/usr/arisawa
hebe%
バグとは言えないが "failed to chdir to ..." のメッセージは要らないのではないだろうか?

なお "mbook$" は僕の MacBook からの、 "hebe%" は僕の Plan9 ホストからのプロンプトである。

References

[1] http://9p.io/magic/man2html/1/cpu

factotum

factotum とは?

factotum とは Plan9 の authentication agent である。
誰の agent か? factotum の実行者の agent である。
factotum は多様なサーバーと多様なユーザー名をサポートする。factotum によってサーバーに接続するたびにパスワードを入れる煩わしさから開放される。もちろん、そのためには認証キーを factotum に与えておく必要がある。

認証キーは例えば次のようなものである。

key proto=p9sk1 dom=local user=arisawa !password=blackcat
key proto=p9sk1 dom=maia.local user=glenda !password=p9mascot
key proto=p9sk1 dom=local user=alice !password=wonderland
"proto" とは認証プロトコルであり、"p9sk1" の他に多彩なプロトコルがサポートされている。
factotum の実行者が arisawa であっても、必ずしも arisawa として接続したいわけではない。ホスト側に alice のアカウントを持っており、alice として接続したいこともある。従って factotum に与えるキーは、アカウントを持つ全てのホストと、そこでのユーザー名を含んでよい。

invocation

secstore を使わない場合には

factotum -n
として起動しておく。

factotum が正しくインストールされていれば

mbook$ ls -l /mnt/factotum
ls: confirm: Resource busy
ls: log: Resource busy
ls: needkey: Resource busy
total 0
-r--------  1 arisawa  staff  0  9 22 10:56 conv
-rw-------  1 arisawa  staff  0  9 22 10:56 ctl
-r--r--r--  1 arisawa  staff  0  9 22 10:56 proto
-rw-rw-rw-  1 arisawa  staff  0  9 22 10:56 rpc
mbook$ cat /mnt/factotum/ctl
key proto=p9sk1 dom=local user=arisawa !password?
key proto=dp9ik dom=local user=arisawa !password?
key proto=p9sk1 dom=local user=glenda !password?
key proto=p9sk1 dom=local user=alice !password?
mbook$
となっている。
なお "Resource busy" は気にしなくてもよい。僕の Linux での環境では、この "busy" は出ていない。

drawterm_russ は Plan9port の factotum との相性が良い。本来は drawterm_cinap もそうあるべであるが、僕の環境では何故か相性が悪く drawterm を実行するたびにパスワードの入力が求められる。その代わり drawterm_cinap には aan フィルターがサポートされていて、これを使うとホストとの断線が発生しない。クライアントが一晩スリープ状態に入っても、再開すれば drawterm はホストと接続している。これは非常にありがたい。

ところで drawterm の password の入力プロンプトはホストが出しているのではなくではなくクライアントサイドにある factotum が出している。クライアントの factotum はホストの factotum と challenge/respose 法によって認証しあっている。つまりユーザー認証とホスト認証が兼ねられている。ホストにパスワードを渡さず、また通信路にパスワード情報が全く流れないので優れた認証方法と言える。

drawterm は内部に factotum を持っている。drawterm はミニ Plan9 とでも言える構造を内部に持っていて、Plan9 的な名前空間の編成がサポートされている。多分この部分が最も難しい。

hebe% cd /mnt/term
hebe% ls -l
...
d-rwxr-xr-x M 8509 arisawa arisawa  2142 Apr 20  2020 sbin
d-r-xr-xr-x M 8509 arisawa arisawa     0 Sep 19 12:41 srv
d-rwxr-xr-x M 8509 arisawa arisawa   170 Sep 20 15:31 srv
d-rwxr-xr-x M 8509 arisawa arisawa   374 Feb 19  2017 sw
d-rwxrwxrwx M 8509 arisawa arisawa  1598 Sep 20 19:38 tmp
...
hebe% ls -l srv
ls: srv: ken has left the building
hebe%
この ken は言うまでもなく Ken Thompson である。これは Russ によるメッセージのはずで、易しいなら Russ はこんな泣き言を言わずに問題を解決したはずである。

なお "srv" が2つ現れているのは、1つは mbook に Plan9port を導入した際に僕が作った /srv、もう一つは drawterm の内部の名前空間の /srv であろう。これらが /mnt/term に見えていると考えられる。