summaryrefslogtreecommitdiff
path: root/appl/wm/rmtdir.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/wm/rmtdir.b')
-rw-r--r--appl/wm/rmtdir.b215
1 files changed, 215 insertions, 0 deletions
diff --git a/appl/wm/rmtdir.b b/appl/wm/rmtdir.b
new file mode 100644
index 00000000..d63d409a
--- /dev/null
+++ b/appl/wm/rmtdir.b
@@ -0,0 +1,215 @@
+implement WmRmtdir;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+ draw: Draw;
+
+include "tk.m";
+ tk: Tk;
+ Toplevel: import tk;
+
+include "tkclient.m";
+ tkclient: Tkclient;
+
+include "keyring.m";
+include "security.m";
+
+t: ref Toplevel;
+
+WmRmtdir: module
+{
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+};
+
+Wm: module
+{
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+};
+
+rmt_config := array[] of {
+ "frame .f",
+ "label .f.l -text Address:",
+ "entry .f.e",
+ "pack .f.l .f.e -side left",
+ "label .status -text {Enter net!machine ...} -anchor w",
+ "pack .Wm_t .status .f -fill x",
+ "bind .f.e <Key-\n> {send cmd dial}",
+ "frame .b",
+ "radiobutton .b.none -variable alg -value none -anchor w -text '"+
+ "Authentication without SSL",
+ "radiobutton .b.clear -variable alg -value clear -anchor w -text '"+
+ "Authentication with SSL clear",
+ "radiobutton .b.sha -variable alg -value sha -anchor w -text '"+
+ "Authentication with SHA hash",
+ "radiobutton .b.md5 -variable alg -value md5 -anchor w -text '"+
+ "Authentication with MD5 hash",
+ "radiobutton .b.rc4 -variable alg -value rc4 -anchor w -text '"+
+ "Authentication with RC4 encryption",
+ "radiobutton .b.sharc4 -variable alg -value sha/rc4 -anchor w -text '"+
+ "Authentication with SHA and RC4",
+ "radiobutton .b.md5rc4 -variable alg -value md5/rc4 -anchor w -text '"+
+ "Authentication with MD5 and RC4",
+ "pack .b.none .b.clear .b.sha .b.md5 .b.rc4 .b.sharc4 .b.md5rc4 -fill x",
+ "pack .b -fill x",
+ ".b.none invoke",
+ "update",
+};
+
+init(ctxt: ref Draw->Context, nil: list of string)
+{
+ menubut : chan of string;
+
+ sys = load Sys Sys->PATH;
+ if (ctxt == nil) {
+ sys->fprint(sys->fildes(2), "rmtdir: no window context\n");
+ raise "fail:bad context";
+ }
+ draw = load Draw Draw->PATH;
+ tk = load Tk Tk->PATH;
+ tkclient= load Tkclient Tkclient->PATH;
+
+ tkclient->init();
+
+ (t, menubut) = tkclient->toplevel(ctxt, "", sysname()+": Remote Connection", 0);
+
+ cmd := chan of string;
+ tk->namechan(t, cmd, "cmd");
+
+ for (i:=0; i<len rmt_config; i++)
+ tk->cmd(t, rmt_config[i]);
+ tkclient->onscreen(t, nil);
+ tkclient->startinput(t, "kbd"::"ptr"::nil);
+
+ for(;;) alt {
+ s := <-t.ctxt.kbd =>
+ tk->keyboard(t, s);
+ s := <-t.ctxt.ptr =>
+ tk->pointer(t, *s);
+ s := <-t.ctxt.ctl or
+ s = <-t.wreq or
+ s = <-menubut =>
+ tkclient->wmctl(t, s);
+ <-cmd =>
+ addr := tk->cmd(t, ".f.e get");
+ status("Dialing");
+ (ok, c) := sys->dial(netmkaddr(addr, "tcp", "styx"), nil);
+ if(ok < 0) {
+ tk->cmd(t, ".status configure -text {Failed: "+
+ sys->sprint("%r")+"}; update");
+ break;
+ }
+ status("Authenticate");
+ alg := tk->cmd(t, "variable alg");
+
+ kr := load Keyring Keyring->PATH;
+ if(kr == nil){
+ tk->cmd(t, ".status configure -text {Error: can't load module Keyring "+
+ sys->sprint("%r")+"}; update");
+ break;
+ }
+
+ user := user();
+ kd := "/usr/" + user + "/keyring/";
+ cert := kd + netmkaddr(addr, "tcp", "");
+ (ok, nil) = sys->stat(cert);
+ if(ok < 0)
+ cert = kd + "default";
+
+ ai := kr->readauthinfo(cert);
+ if(ai == nil){
+ tk->cmd(t, ".status configure -text {Error: certificate for "+
+ sys->sprint("%s",addr)+" not found}; update");
+ wmgetauthinfo := load Wm "/dis/wm/wmgetauthinfo.dis";
+ if(wmgetauthinfo == nil){
+ tk->cmd(t, ".status configure -text {Error: can't load module wmgetauthinfo.dis}; update");
+ exit;
+ }
+ spawn wmgetauthinfo->init(ctxt, nil);
+ break;
+ }
+
+ au := load Auth Auth->PATH;
+ if(au == nil){
+ tk->cmd(t, ".status configure -text {Error: can't load module Auth "+
+ sys->sprint("%r")+"; update");
+ break;
+ }
+
+ err := au->init();
+ if(err != nil){
+ tk->cmd(t, ".status configure -text {Error: "+
+ sys->sprint("%s", err)+"; update");
+ break;
+ }
+
+ fd: ref Sys->FD;
+ (fd, err) = au->client(alg, ai, c.dfd);
+ if(fd == nil){
+ tk->cmd(t, ".status configure -text {Error: authentication failed: "+
+ sys->sprint("%s",err)+"; update");
+ break;
+ }
+
+ status("Mount");
+ sys->pctl(sys->FORKNS, nil); # don't fork before authentication
+ n := sys->mount(fd, nil, "/n/remote", sys->MREPL, "");
+ if(n < 0) {
+ tk->cmd(t, ".status configure -text {Mount failed: "+
+ sys->sprint("%r")+"}; update");
+ break;
+ }
+ wmdir := load Wm "/dis/wm/dir.dis";
+ spawn wmdir->init(ctxt, "wm/dir" :: "/n/remote" :: nil);
+ return;
+ }
+}
+
+status(s: string)
+{
+ tk->cmd(t, ".status configure -text {"+s+"}; update");
+}
+
+sysname(): string
+{
+ fd := sys->open("#c/sysname", sys->OREAD);
+ if(fd == nil)
+ return "Anon";
+ buf := array[128] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return "Anon";
+ return string buf[0:n];
+}
+
+user(): string
+{
+ sys = load Sys Sys->PATH;
+
+ fd := sys->open("/dev/user", sys->OREAD);
+ if(fd == nil)
+ return "";
+
+ buf := array[128] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return "";
+
+ return string buf[0:n];
+}
+
+netmkaddr(addr, net, svc: string): string
+{
+ if(net == nil)
+ net = "net";
+ (n, l) := sys->tokenize(addr, "!");
+ if(n <= 1){
+ if(svc== nil)
+ return sys->sprint("%s!%s", net, addr);
+ return sys->sprint("%s!%s!%s", net, addr, svc);
+ }
+ if(svc == nil || n > 2)
+ return addr;
+ return sys->sprint("%s!%s", addr, svc);
+}