adding experimental rcpu service

this is a reimplementation of cpu and import utilities in rc using a tlsclient
and tlssrv as the encryption and authentication layers. there is only one new
service, which after authentication and encryption setup accepts an arbitrary
rc script over the network and executes it with the standard filedescriptors
redirected to the conversaion (this is *after* authentication and in the
context of the authorized user).

the new rcpu program has a few improvements over cpu(1):

- doesnt mangle program arguments
- the remote process will get the clients standard file descriptors, so error
  and output are separated and you can consume the clients input from the
  remote side :-)
- forwards error status of remote process

theres no backwards mode for rimport, but a new program called rexport
for the same purpose.

all these services use exportfs without the bolted on initial handshake,
so the hope is to clean up exportfs in the future and remove all the ugly
crap in there.
This commit is contained in:
cinap_lenrek 2016-02-14 05:18:33 +01:00
parent 4fe7daeca4
commit fde5906b30
6 changed files with 285 additions and 0 deletions

84
rc/bin/rconnect Executable file
View file

@ -0,0 +1,84 @@
#!/bin/rc
rfork e
argv0=$0
fn usage {
echo 'usage:' $argv0 '[-p] [-u user] [-k keyspec] host remotescript localcommand ...' >[1=2]
exit 'usage'
}
fn pvar {
while(! ~ $#* 0){
~ $#$1 0 || path=/dev/null builtin whatis $1
shift
}
}
filter=()
keyspec=()
while(~ $1 -*){
switch($1){
case -p; filter=aan
case *
~ $#* 1 && usage
switch($1){
case -k; keyspec=($keyspec $2)
case -u; keyspec=($keyspec `{user=$2 pvar user})
case *; usage
}
shift
}
shift
}
~ $#* 0 1 2 && usage
host=$1
shift
fn sendscript {
echo -n $host >/proc/$pid/args
cat $1 >/env/v; wc -c </env/v; cat /env/v; rm /env/v
shift
$*
}
if(~ $filter aan){
fn aanserver {
~ $#netdir 1 || netdir=/net/tcp/clone
netdir=`{basename -d $netdir} || exit
<>$netdir/clone {
netdir=$netdir/`{read} || exit
>[3] $netdir/ctl {
echo -n 'announce *!0' >[1=3]
echo `{cat $netdir/local} || exit
bind '#|' /mnt/aan || exit
exec aan $netdir <>/mnt/aan/data1 >[1=0] >[2]/dev/null &
}
}
<>/mnt/aan/data >[1=0] >[2]/dev/null {
rfork n
fn server {
echo -n aanserver $netdir >/proc/$pid/args
. <{n=`{read} && ! ~ $#n 0 && read -c $n} >[2=1]
}
rm -f /env/^'fn#aanserver'
exec tlssrv -A /bin/rc -c server
exit
}
}
fn aanclient {
host=`{echo $host | sed 's/(.*)!([^!]+)$/\1/'}^!^`{read | sed 's/(.*)!([^!]+)$/\2/'} || exit
tlsclient -a -o <>{rfork s; aan -c $host >[1=0]} /bin/rc -c 'sendscript $*' $*
}
exec $argv0 -k $"keyspec $host <{builtin whatis aanserver; echo aanserver} aanclient $*
exit
}
switch($host){
case *!*!*;
case *!*; host=$host!rcpu
case *; host=net!$host!rcpu
}
exec tlsclient -ak $"keyspec $host /bin/rc -c 'sendscript $*' $*

83
rc/bin/rcpu Executable file
View file

@ -0,0 +1,83 @@
#!/bin/rc
rfork e
argv0=$0
fn usage {
echo 'usage:' $argv0 '[-p] [-h host] [-u user] [-k keypattern] [-P patternfile] [-c cmd arg ...]' >[1=2]
exit 'usage'
}
fn server {
mount -nc /fd/0 /mnt/term || exit
bind -q /mnt/term/dev/cons /dev/cons
</mnt/term/fd/10 >/mnt/term/fd/11 >[2]/mnt/term/fd/12 {
~ $#dir 0 || cd $"dir || echo 'can''t change directory: '^$"dir >[1=2]
switch($#cmd){
case 0; cmd=(rc -li)
case 1; cmd=(rc -lc $cmd)
case *; cmd=(rc -lc '$*' $cmd)
}
rm -f /env/^(cmd dir 'fn#server')
service=cpu exec $cmd
} &
if(test -d /mnt/term/mnt/cpunote) {
rfork e
mainproc=$apid
exec cat </mnt/term/mnt/cpunote/data >/proc/$mainproc/notepg &
noteproc=$apid
wait $mainproc
echo -n $status >/mnt/term/env/rstatus >[2]/dev/null
echo -n kill >/proc/$noteproc/note
}
}
fn client {
echo -n >/env/rstatus
rfork n
bind '#|' /mnt/cpunote || exit
</fd/0 exec $exportfs -r / &
</dev/null >/mnt/cpunote/data1 {
fn sigkill { echo -n kill >/mnt/cpunote/data1 }
fn sighup { echo -n hangup >/mnt/cpunote/data1 }
fn sigint { status=interrupted }
wait
while(~ $status interrupted) {
echo -n interrupt
wait
}
status=`{cat /env/rstatus}
exit $"status
}
}
cmd=()
host='$cpu'
exportfs=/bin/exportfs
connect=/bin/rconnect
while(~ $1 -*){
switch($1){
case -p; connect=($connect $1)
case *
~ $#* 1 && usage
switch($1){
case -P; exportfs=($exportfs $1 $2)
case -[uk]; connect=($connect $1 $2)
case -h; host=$2
case -c; cmd=$*(2-); *=()
case *; usage
}
shift
}
shift
}
~ $#* 0 || usage
fn pvar {
while(! ~ $#* 0){
~ $#$1 0 || path=/dev/null builtin whatis $1
shift
}
}
exec $connect $host <{dir=`{pwd} pvar dir cmd; builtin whatis server; echo server} client <[10=0] >[11=1] >[12=2]

57
rc/bin/rexport Executable file
View file

@ -0,0 +1,57 @@
#!/bin/rc
rfork e
argv0=$0
fn usage {
echo 'usage:' $argv0 '[options] [-s remotesrv] [-m remotemtpt] tree host [remotecmd [args ...]]' >[1=2]
exit 'usage'
}
fn domount {
if(~ $#sname 1){
rm -f /srv/$sname
echo -n 0 >/srv/$sname
}
~ $#mtpt 0 || mount -n $mopt /fd/0 $mtpt || exit
~ $#cmd 0 || service=import exec $cmd </dev/null >/dev/null >[2=1]
}
sname=()
mopt=()
mtpt=()
exportfs=/bin/exportfs
connect=/bin/rconnect
while(~ $1 -*){
switch($1){
case -p; connect=($connect $1)
case -[abcCnq]*; mopt=($mopt $1)
case *
~ $#* 1 && usage
switch($1){
case -P; exportfs=($exportfs $1 $2)
case -[uk]; connect=($connect $1 $2)
case -s; sname=`{basename $2}
case -m; mtpt=$2
case *; usage
}
shift
}
shift
}
~ $#* 0 1 && usage
exportfs=($exportfs -r $1)
shift
host=$1
shift
cmd=$*
fn pvar {
while(! ~ $#* 0){
~ $#$1 0 || path=/dev/null builtin whatis $1
shift
}
}
exec $connect $host <{pvar sname mtpt mopt cmd; builtin whatis domount; echo domount} exec $exportfs

52
rc/bin/rimport Executable file
View file

@ -0,0 +1,52 @@
#!/bin/rc
rfork e
argv0=$0
fn usage {
echo 'usage:' $argv0 '[options] host tree [mountpoint]' >[1=2]
exit 'usage'
}
fn domount {
if(~ $#sname 1){
rm -f /srv/$sname
echo -n 0 >/srv/$sname
}
~ $#mtpt 0 || mount -n $mopt /fd/0 $mtpt
}
tree=()
mopt=()
mtpt=()
sname=()
exportfs=/bin/exportfs
connect=/bin/rconnect
while(~ $1 -*){
switch($1){
case -p; connect=($connect $1)
case -[abcCnq]*; mopt=($mopt $1)
case *
~ $#* 1 && usage
switch($1){
case -[uk]; connect=($connect $1 $2)
case -s; sname=`{basename $2}
case *; usage
}
shift
}
shift
}
switch($#*){
case 2 3; tree=$2; mtpt=$$#*
case *; usage
}
fn pvar {
while(! ~ $#* 0){
~ $#$1 0 || path=/dev/null builtin whatis $1
shift
}
}
exec $connect $1 <{pvar tree; echo exec $exportfs -r '$tree'} domount

8
rc/bin/service/tcp17019 Executable file
View file

@ -0,0 +1,8 @@
#!/bin/rc
netdir=$3
remote=$2!`{cat $3/remote}
fn server {
echo -n $netdir $remote >/proc/$pid/args
. <{n=`{read} && ! ~ $#n 0 && read -c $n} >[2=1]
}
exec tlssrv -a /bin/rc -c server

View file

@ -284,6 +284,7 @@ tcp=exportfs port=17007
tcp=rexexec port=17009 tcp=rexexec port=17009
tcp=ncpu port=17010 tcp=ncpu port=17010
tcp=cpu port=17013 tcp=cpu port=17013
tcp=rcpu port=17019
tcp=glenglenda1 port=17020 tcp=glenglenda1 port=17020
tcp=glenglenda2 port=17021 tcp=glenglenda2 port=17021
tcp=glenglenda3 port=17022 tcp=glenglenda3 port=17022